From fd67354cc21c5d703f97ecf0bf1f7a210dcbea66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robson=20J=C3=BAnior?= Date: Thu, 25 Jun 2026 11:01:50 -0300 Subject: [PATCH 1/4] fix: run required check to dev opened pull requests --- .github/workflows/governance.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/governance.yml b/.github/workflows/governance.yml index 205161047..4e47071c0 100644 --- a/.github/workflows/governance.yml +++ b/.github/workflows/governance.yml @@ -2,9 +2,9 @@ name: Governance Pipeline on: pull_request: - branches: [main] + branches: [main, dev] push: - branches: [main] + branches: [main, dev] permissions: contents: read From ca71b012bd6d4d8d1f1a738ff086e5edc9253ce3 Mon Sep 17 00:00:00 2001 From: Gab Date: Fri, 26 Jun 2026 14:01:12 -0500 Subject: [PATCH 2/4] [ENG-46485] feat(theme): add progress-indeterminate animation utilities --- packages/theme/dist/v3/globals.css | 2 ++ packages/theme/dist/v3/globals.scss | 2 ++ packages/theme/dist/v4/globals.css | 2 ++ packages/theme/dist/v4/globals.scss | 2 ++ .../src/tokens/primitives/animations/animate.js | 4 ++++ packages/theme/src/tokens/semantic/animations.js | 16 ++++++++++++++++ 6 files changed, 28 insertions(+) diff --git a/packages/theme/dist/v3/globals.css b/packages/theme/dist/v3/globals.css index 2535a422c..68cb47fb7 100644 --- a/packages/theme/dist/v3/globals.css +++ b/packages/theme/dist/v3/globals.css @@ -448,6 +448,8 @@ --animate-bounce: bounce 1s infinite; --animate-popup-scale-in: popupScaleIn 150ms cubic-bezier(0.39, 0.57, 0.56, 1); --animate-popup-scale-out: popupScaleOut 110ms cubic-bezier(0.55, 0.09, 0.68, 0.53); + --animate-progress-indeterminate: progressIndeterminate 2100ms cubic-bezier(0.39, 0.57, 0.56, 1) infinite; + --animate-progress-indeterminate-short: progressIndeterminateShort 2100ms cubic-bezier(0.17, 0.84, 0.44, 1) 1100ms infinite; --ring-offset: 0.5px; /* ── Containers ── */ diff --git a/packages/theme/dist/v3/globals.scss b/packages/theme/dist/v3/globals.scss index 2535a422c..68cb47fb7 100644 --- a/packages/theme/dist/v3/globals.scss +++ b/packages/theme/dist/v3/globals.scss @@ -448,6 +448,8 @@ --animate-bounce: bounce 1s infinite; --animate-popup-scale-in: popupScaleIn 150ms cubic-bezier(0.39, 0.57, 0.56, 1); --animate-popup-scale-out: popupScaleOut 110ms cubic-bezier(0.55, 0.09, 0.68, 0.53); + --animate-progress-indeterminate: progressIndeterminate 2100ms cubic-bezier(0.39, 0.57, 0.56, 1) infinite; + --animate-progress-indeterminate-short: progressIndeterminateShort 2100ms cubic-bezier(0.17, 0.84, 0.44, 1) 1100ms infinite; --ring-offset: 0.5px; /* ── Containers ── */ diff --git a/packages/theme/dist/v4/globals.css b/packages/theme/dist/v4/globals.css index c2355d64f..42a0b2102 100644 --- a/packages/theme/dist/v4/globals.css +++ b/packages/theme/dist/v4/globals.css @@ -449,6 +449,8 @@ --animate-bounce: bounce 1s infinite; --animate-popup-scale-in: popupScaleIn 150ms cubic-bezier(0.39, 0.57, 0.56, 1); --animate-popup-scale-out: popupScaleOut 110ms cubic-bezier(0.55, 0.09, 0.68, 0.53); + --animate-progress-indeterminate: progressIndeterminate 2100ms cubic-bezier(0.39, 0.57, 0.56, 1) infinite; + --animate-progress-indeterminate-short: progressIndeterminateShort 2100ms cubic-bezier(0.17, 0.84, 0.44, 1) 1100ms infinite; --ring-offset: 0.5px; --container-px: 1rem; --container-py: 4rem; diff --git a/packages/theme/dist/v4/globals.scss b/packages/theme/dist/v4/globals.scss index c2355d64f..42a0b2102 100644 --- a/packages/theme/dist/v4/globals.scss +++ b/packages/theme/dist/v4/globals.scss @@ -449,6 +449,8 @@ --animate-bounce: bounce 1s infinite; --animate-popup-scale-in: popupScaleIn 150ms cubic-bezier(0.39, 0.57, 0.56, 1); --animate-popup-scale-out: popupScaleOut 110ms cubic-bezier(0.55, 0.09, 0.68, 0.53); + --animate-progress-indeterminate: progressIndeterminate 2100ms cubic-bezier(0.39, 0.57, 0.56, 1) infinite; + --animate-progress-indeterminate-short: progressIndeterminateShort 2100ms cubic-bezier(0.17, 0.84, 0.44, 1) 1100ms infinite; --ring-offset: 0.5px; --container-px: 1rem; --container-py: 4rem; diff --git a/packages/theme/src/tokens/primitives/animations/animate.js b/packages/theme/src/tokens/primitives/animations/animate.js index f40f7c7a4..580c30adc 100644 --- a/packages/theme/src/tokens/primitives/animations/animate.js +++ b/packages/theme/src/tokens/primitives/animations/animate.js @@ -12,6 +12,8 @@ export const duration = { 'moderate-02': '240ms', 'slow-01': '400ms', 'slow-02': '700ms', + 'slow-03': '1100ms', + 'slow-04': '2100ms', }; export const animate = { @@ -21,6 +23,8 @@ export const animate = { bounce: 'bounce 1s infinite', 'popup-scale-in': `popupScaleIn ${duration['moderate-01']} ${curve['productive-entrance']}`, 'popup-scale-out': `popupScaleOut ${duration['fast-02']} ${curve['productive-exit']}`, + 'progress-indeterminate': `progressIndeterminate ${duration['slow-04']} ${curve['productive-entrance']} infinite`, + 'progress-indeterminate-short': `progressIndeterminateShort ${duration['slow-04']} ${curve['expressive-entrance']} ${duration['slow-03']} infinite`, }; export default { animate, curve, duration }; diff --git a/packages/theme/src/tokens/semantic/animations.js b/packages/theme/src/tokens/semantic/animations.js index 8afa5e274..cacd6f904 100644 --- a/packages/theme/src/tokens/semantic/animations.js +++ b/packages/theme/src/tokens/semantic/animations.js @@ -37,6 +37,12 @@ export const animations = () => { animation: 'popupScaleOut 110ms cubic-bezier(0.55, 0.09, 0.68, 0.53)', transformOrigin: 'var(--popup-origin, center)', }, + '.animate-progress-indeterminate': { + animation: 'progressIndeterminate 2100ms cubic-bezier(0.39, 0.57, 0.56, 1) infinite', + }, + '.animate-progress-indeterminate-short': { + animation: 'progressIndeterminateShort 2100ms cubic-bezier(0.17, 0.84, 0.44, 1) 1100ms infinite', + }, }; // Keyframes components @@ -69,6 +75,16 @@ export const animations = () => { '0%': { opacity: '1', transform: 'scale(1)' }, '100%': { opacity: '0', transform: 'scale(0.95)' }, }, + '@keyframes progressIndeterminate': { + '0%': { 'inset-inline-start': '-35%', 'inset-inline-end': '100%' }, + '60%': { 'inset-inline-start': '100%', 'inset-inline-end': '-90%' }, + '100%': { 'inset-inline-start': '100%', 'inset-inline-end': '-90%' }, + }, + '@keyframes progressIndeterminateShort': { + '0%': { 'inset-inline-start': '-200%', 'inset-inline-end': '100%' }, + '60%': { 'inset-inline-start': '107%', 'inset-inline-end': '-8%' }, + '100%': { 'inset-inline-start': '107%', 'inset-inline-end': '-8%' }, + }, }; const variants = ['responsive', 'hover', 'focus', 'active', 'motion-safe', 'motion-reduce']; From 85664fb0154bbc51fdfaa665ae5e1301b079d4fd Mon Sep 17 00:00:00 2001 From: Gab Date: Fri, 26 Jun 2026 14:01:36 -0500 Subject: [PATCH 3/4] [ENG-46485] feat(webkit): add ProgressBar (feedback) --- .specs/progress-bar.md | 126 +++++++++++ .../progress-bar/ProgressBar.stories.js | 214 ++++++++++++++++++ packages/webkit/package.json | 1 + .../feedback/progress-bar/package.json | 11 + .../feedback/progress-bar/progress-bar.vue | 62 +++++ 5 files changed, 414 insertions(+) create mode 100644 .specs/progress-bar.md create mode 100644 apps/storybook/src/stories/components/feedback/progress-bar/ProgressBar.stories.js create mode 100644 packages/webkit/src/components/feedback/progress-bar/package.json create mode 100644 packages/webkit/src/components/feedback/progress-bar/progress-bar.vue diff --git a/.specs/progress-bar.md b/.specs/progress-bar.md new file mode 100644 index 000000000..238f2bf81 --- /dev/null +++ b/.specs/progress-bar.md @@ -0,0 +1,126 @@ +--- +name: progress-bar +category: feedback +structure: monolithic +status: implemented +spec_version: 1 +checksum: 1a7bc9bdc211ad0591a48082474922afe6e508a9b620c45ac30fe79ca782c6d7 +figma: + url: https://www.figma.com/design/t97pXRs7xME3SJDs5iZ5RF/Webkit?node-id=479-870 + node_id: 479:870 +created: 2026-06-26 +last_updated: 2026-06-26 +--- + +# Progress Bar — Component Spec + +## Purpose + +Communicates the progress of an ongoing task as a horizontal bar. Use it for a +determinate value within a range (`value` / `max`) or, when progress can't be +measured, as an indeterminate loading indicator. Unlike `skeleton` (placeholder +geometry) or `status-indicator` (discrete state), it expresses a continuous +quantity. + +## Usage + +```vue + + + +``` + +## Props + +| Prop | Type | Default | Required | JSDoc | +|---|---|---|---|---| +| `value` | `number` | `0` | no | Current progress, relative to `max`. | +| `max` | `number` | `100` | no | Upper bound; percentage = `value / max * 100`. | +| `shape` | `'rounded' \| 'flat'` | `'rounded'` | no | Track and fill corner-radius variant. | +| `size` | `'small' \| 'medium' \| 'large'` | `'medium'` | no | Bar height token. | +| `indeterminate` | `boolean` | `false` | no | Loading state; animates a sliding segment and ignores `value`. | + +## Events + +| _none_ | — | — | + +## Slots + +| _none_ | — | — | + +## States + +- Visual states: `default`, `indeterminate` +- `data-shape` mirrors the `shape` prop: `rounded` | `flat` +- `data-size` mirrors the `size` prop: `small` | `medium` | `large` +- `data-indeterminate` is present while `indeterminate` is `true` + +## Motion & Animations + +| Trigger | Animation / Transition | Token (see `.claude/docs/DESIGN.md` § Animations) | Reduced-motion fallback | +|---|---|---|---| +| `value` change (determinate) | `transition-[width] duration-moderate-02 ease-productive-entrance` (width morph) | duration/curve aliases from `animate.js` (240ms · productive-entrance) | `motion-reduce:transition-none` | +| `indeterminate` (loading sweep) | `animate-progress-indeterminate` + `animate-progress-indeterminate-short` (two offset bars sweeping across the track via `inset-inline-start`/`inset-inline-end`) | semantic (2.1s · infinite) | `motion-reduce:animate-none` (static fill) | + +## Tokens + +| Region | Token (DESIGN.md) | +|---|---| +| fill | `var(--primary)` | +| shape (rounded) | `var(--shape-elements)` | +| shape (flat) | `var(--shape-flat)` | + + + +## Theme gaps + +| Figma variable | Temporary primitive | Follow-up | +|---|---|---| +| `--bg-surface-raised` (track) | `var(--bg-surface-raised)` | `TODO: document --bg-surface-raised in .claude/docs/DESIGN.md § Colors` | + +## Accessibility (WCAG 2.1 AA) + +- Non-interactive: the bar is not focusable and takes no keyboard input. +- ARIA: root uses `role="progressbar"`. Determinate sets `aria-valuemin="0"`, `aria-valuemax=""`, `aria-valuenow=""`; indeterminate omits `aria-valuenow` and sets `aria-busy="true"`. +- Contrast ≥3:1 between the fill (`var(--primary)`) and the track (`var(--bg-surface-raised)`). +- `motion-reduce:transition-none` on the determinate width morph and `motion-reduce:animate-none` on the indeterminate animation (it falls back to a static fill under reduced motion). + +## Stories (Storybook) + +Composite stories render every variant of an axis side-by-side in a single frame; +the `Indeterminate` story is the state story for the `indeterminate` boolean. + +- Default +- Shapes — composite story rendering `rounded` and `flat` side-by-side (the component's variant axis; stands in for `Types`). +- Sizes — composite story rendering `small`, `medium`, `large` side-by-side. +- Indeterminate — state story for the `indeterminate` prop. +- Simulation — interactive story: a button advances `value` in steps so the reviewer can see the fill's width transition animate on each `value` change. Justified because this motion (the determinate `transition-[width]`) only manifests on a live value change and cannot be shown by a static frame. + +## Constraints — DO NOT + + + +- Do not add props beyond the Props table above. If you need a prop that is not listed, emit `BLOCKED: missing prop ` and stop — do not invent. +- Do not add events beyond the Events table above. Same rule for slots and sub-components. +- Do not invent imports. Every `@aziontech/webkit/*` path must exist in `packages/webkit/package.json#exports`. Every relative import must resolve to a real file. Every npm package must be installed. +- Do not use HEX/RGB/HSL colors, Tailwind palette names (e.g. `bg-blue-500`), raw typography classes (e.g. `text-sm`), `any`, `@ts-ignore`, or `class` inside `defineProps`. +- Do not install or import positioning/animation libraries (`@floating-ui/*`, `popper.js`, `tippy.js`, `gsap`, `framer-motion`, `motion`, `@vueuse/motion`, `@formkit/auto-animate`, drag-drop runtimes, scroll virtualization libs). Use CSS + Vue primitives (``, ``). See `.claude/rules/dependencies.md`. +- Do not improvise animations. Every `animate-*` / `transition-*` class must come from `packages/theme/src/tokens/semantic/animations.js`; every motion-bearing class pairs with `motion-reduce:*` on the same class string; no component-local `@keyframes`. +- Do not create class presets in JavaScript (`const kindClasses = {...}`, `const sharedClasses = [...]`, `const sizeClasses = {...}`, `const rootClasses = computed(...)`). Variants live on `data-*` attributes consumed by Tailwind `data-[attr=value]:`. All utilities live inline on the root element's `class` attribute. No `