pixelize-design-library 2.4.2-beta.62 → 2.4.2-beta.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +75 -2
- package/COMPONENT-GOTCHAS.md +25 -6
- package/DESIGN-GUIDE.md +12 -5
- package/dist/Components/Button/Button.styles.js +51 -21
- package/dist/Components/Card/CardProps.d.ts +2 -2
- package/dist/Components/ConfirmDialog/ConfirmDialog.js +2 -1
- package/dist/Components/CustomModulesTable/CustomModulesTable.js +6 -4
- package/dist/Components/CustomModulesTable/EditModuleModal.js +2 -1
- package/dist/Components/DatePicker/RangeDatePicker.js +2 -1
- package/dist/Components/DatePicker/SingleDatePicker.js +2 -1
- package/dist/Components/DatePicker/TimeOnlyPicker.js +2 -1
- package/dist/Components/DatePicker/dayStates.js +2 -1
- package/dist/Components/Drawer/Drawer.js +2 -1
- package/dist/Components/Dropdown/DropDown.js +2 -1
- package/dist/Components/FileUpload/FileUpload.js +9 -2
- package/dist/Components/FilterSidebar/FilterSidebar.js +7 -4
- package/dist/Components/KanbanBoard/AccountCard.js +4 -2
- package/dist/Components/NavigationBar/NavigationBar.js +3 -2
- package/dist/Components/Notification/Notification.js +4 -3
- package/dist/Components/NotificationBell/NotificationPanel.js +4 -3
- package/dist/Components/OrganizationDetails/CreateOrgModal.js +2 -1
- package/dist/Components/OrganizationDetails/OrganizationDetails.js +5 -3
- package/dist/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +7 -3
- package/dist/Components/SearchSelect/SearchSelect.js +42 -21
- package/dist/Components/SearchSelect/searchSelectNav.d.ts +13 -0
- package/dist/Components/SearchSelect/searchSelectNav.js +40 -0
- package/dist/Components/Select/SelectPopup.js +2 -1
- package/dist/Components/SelectSearch/SelectSearch.js +2 -1
- package/dist/Components/SettingRow/SettingRow.js +2 -1
- package/dist/Components/SettingRow/SettingsSection.js +2 -1
- package/dist/Components/SideBar/SecondaryBar.js +4 -3
- package/dist/Components/SideBar/SideBar.js +16 -13
- package/dist/Components/SideBar/SideBarProps.d.ts +1 -1
- package/dist/Components/SideBar/components/MenuItemBox.js +7 -4
- package/dist/Components/SideBar/components/MenuPopoverContent.js +2 -1
- package/dist/Components/SideBar/components/OtherApps.js +2 -1
- package/dist/Components/SideBar/components/PinnedSection.js +7 -4
- package/dist/Components/SideBar/sidebarMotion.d.ts +2 -0
- package/dist/Components/SideBar/sidebarMotion.js +6 -0
- package/dist/Components/SignInActivityTable/SignInActivityTable.js +6 -4
- package/dist/Components/StageProgress/StageItem.js +5 -2
- package/dist/Components/StageProgress/StepperStage.js +2 -2
- package/dist/Components/StatCard/StatCard.js +2 -1
- package/dist/Components/Table/Table.js +6 -2
- package/dist/Components/Table/components/TableActions.js +3 -2
- package/dist/Components/Table/filters/CompactSelect.js +2 -1
- package/dist/Components/Table/settings/TableSettings.js +7 -2
- package/dist/Components/Table/variants/classic.js +3 -2
- package/dist/Components/Timeline/Timeline.js +11 -4
- package/dist/Components/Toaster/Toaster.js +19 -8
- package/dist/Components/Toggle/TableToggle.js +5 -2
- package/dist/Components/UserDetails/AddUserModal.js +2 -1
- package/dist/Components/UserDetails/ChangeRoleModal.js +2 -1
- package/dist/Components/UserDetails/UserDetails.js +3 -1
- package/dist/Theme/chakra/Card.styles.d.ts +7 -1
- package/dist/Theme/chakra/Card.styles.js +4 -1
- package/dist/Theme/chakra/Menu.styles.d.ts +3 -5
- package/dist/Theme/chakra/Menu.styles.js +3 -0
- package/dist/Theme/chakra/Popover.styles.d.ts +2 -11
- package/dist/Theme/chakra/Popover.styles.js +2 -0
- package/dist/Theme/chakra/common.web.d.ts +4 -0
- package/dist/Theme/chakra/componentStyles.d.ts +11 -3
- package/dist/Theme/chakra/componentStyles.js +10 -6
- package/dist/Theme/chakra/motion.d.ts +1 -0
- package/dist/Theme/chakra/motion.js +2 -1
- package/dist/Theme/chakra/overlay.styles.d.ts +5 -0
- package/dist/Theme/chakra/overlay.styles.js +4 -1
- package/dist/Theme/themeProps.d.ts +4 -0
- package/dist/Theme/tokens/brands/index.d.ts +1 -0
- package/dist/Theme/tokens/brands/index.js +17 -1
- package/dist/Theme/tokens/brands/radiant/palette.light.js +15 -0
- package/dist/Theme/tokens/brands/rosewood/palette.light.js +10 -10
- package/dist/Theme/tokens/brands/zinc/palette.dark.d.ts +7 -29
- package/dist/Theme/tokens/brands/zinc/palette.dark.js +3 -35
- package/dist/Theme/tokens/builders/buildDarkPalette.d.ts +6 -1
- package/dist/Theme/tokens/builders/buildDarkPalette.js +37 -8
- package/dist/Theme/tokens/builders/mutedText.d.ts +1 -1
- package/dist/Theme/tokens/builders/mutedText.js +13 -3
- package/dist/Theme/tokens/builders/planeStep.d.ts +4 -0
- package/dist/Theme/tokens/builders/planeStep.js +20 -0
- package/dist/Theme/tokens/builders/planes.d.ts +4 -0
- package/dist/Theme/tokens/builders/planes.js +33 -0
- package/dist/Theme/tokens/builders/skeletonShimmer.d.ts +9 -0
- package/dist/Theme/tokens/builders/skeletonShimmer.js +25 -0
- package/dist/Theme/tokens/builders/surfaceRaised.d.ts +3 -1
- package/dist/Theme/tokens/builders/surfaceRaised.js +18 -8
- package/dist/Theme/tokens/builders/surfaceRungs.js +3 -1
- package/dist/Theme/tokens/primitives/index.d.ts +2 -2
- package/dist/Theme/tokens/primitives/index.js +4 -1
- package/dist/Theme/tokens/primitives/motion.d.ts +1 -0
- package/dist/Theme/tokens/primitives/motion.js +2 -1
- package/dist/Theme/tokens/primitives/shadows.d.ts +16 -0
- package/dist/Theme/tokens/primitives/shadows.js +56 -6
- package/dist/Theme/tokens/primitives/typography.js +1 -1
- package/dist/esm/Components/Button/Button.styles.js +54 -24
- package/dist/esm/Components/ConfirmDialog/ConfirmDialog.js +2 -1
- package/dist/esm/Components/CustomModulesTable/CustomModulesTable.js +6 -4
- package/dist/esm/Components/CustomModulesTable/EditModuleModal.js +2 -1
- package/dist/esm/Components/DatePicker/RangeDatePicker.js +2 -1
- package/dist/esm/Components/DatePicker/SingleDatePicker.js +2 -1
- package/dist/esm/Components/DatePicker/TimeOnlyPicker.js +2 -1
- package/dist/esm/Components/DatePicker/dayStates.js +2 -1
- package/dist/esm/Components/Drawer/Drawer.js +2 -1
- package/dist/esm/Components/Dropdown/DropDown.js +2 -1
- package/dist/esm/Components/FileUpload/FileUpload.js +10 -3
- package/dist/esm/Components/FilterSidebar/FilterSidebar.js +7 -4
- package/dist/esm/Components/KanbanBoard/AccountCard.js +4 -2
- package/dist/esm/Components/NavigationBar/NavigationBar.js +3 -2
- package/dist/esm/Components/Notification/Notification.js +4 -3
- package/dist/esm/Components/NotificationBell/NotificationPanel.js +4 -3
- package/dist/esm/Components/OrganizationDetails/CreateOrgModal.js +2 -1
- package/dist/esm/Components/OrganizationDetails/OrganizationDetails.js +5 -3
- package/dist/esm/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +7 -3
- package/dist/esm/Components/SearchSelect/SearchSelect.js +42 -21
- package/dist/esm/Components/SearchSelect/searchSelectNav.js +32 -0
- package/dist/esm/Components/Select/SelectPopup.js +2 -1
- package/dist/esm/Components/SelectSearch/SelectSearch.js +2 -1
- package/dist/esm/Components/SettingRow/SettingRow.js +2 -1
- package/dist/esm/Components/SettingRow/SettingsSection.js +2 -1
- package/dist/esm/Components/SideBar/SecondaryBar.js +4 -3
- package/dist/esm/Components/SideBar/SideBar.js +17 -14
- package/dist/esm/Components/SideBar/components/MenuItemBox.js +7 -4
- package/dist/esm/Components/SideBar/components/MenuPopoverContent.js +2 -1
- package/dist/esm/Components/SideBar/components/OtherApps.js +2 -1
- package/dist/esm/Components/SideBar/components/PinnedSection.js +7 -4
- package/dist/esm/Components/SideBar/sidebarMotion.js +3 -0
- package/dist/esm/Components/SignInActivityTable/SignInActivityTable.js +6 -4
- package/dist/esm/Components/StageProgress/StageItem.js +5 -2
- package/dist/esm/Components/StageProgress/StepperStage.js +2 -2
- package/dist/esm/Components/StatCard/StatCard.js +2 -1
- package/dist/esm/Components/Table/Table.js +8 -4
- package/dist/esm/Components/Table/components/TableActions.js +3 -2
- package/dist/esm/Components/Table/filters/CompactSelect.js +2 -1
- package/dist/esm/Components/Table/settings/TableSettings.js +8 -3
- package/dist/esm/Components/Table/variants/classic.js +3 -2
- package/dist/esm/Components/Timeline/Timeline.js +11 -4
- package/dist/esm/Components/Toaster/Toaster.js +20 -9
- package/dist/esm/Components/Toggle/TableToggle.js +5 -2
- package/dist/esm/Components/UserDetails/AddUserModal.js +2 -1
- package/dist/esm/Components/UserDetails/ChangeRoleModal.js +2 -1
- package/dist/esm/Components/UserDetails/UserDetails.js +3 -1
- package/dist/esm/Theme/chakra/Card.styles.js +4 -1
- package/dist/esm/Theme/chakra/Menu.styles.js +3 -0
- package/dist/esm/Theme/chakra/Popover.styles.js +2 -0
- package/dist/esm/Theme/chakra/componentStyles.js +10 -6
- package/dist/esm/Theme/chakra/motion.js +1 -0
- package/dist/esm/Theme/chakra/overlay.styles.js +3 -0
- package/dist/esm/Theme/tokens/brands/index.js +16 -0
- package/dist/esm/Theme/tokens/brands/radiant/palette.light.js +15 -0
- package/dist/esm/Theme/tokens/brands/rosewood/palette.light.js +10 -10
- package/dist/esm/Theme/tokens/brands/zinc/palette.dark.js +3 -35
- package/dist/esm/Theme/tokens/builders/buildDarkPalette.js +38 -9
- package/dist/esm/Theme/tokens/builders/mutedText.js +12 -2
- package/dist/esm/Theme/tokens/builders/planeStep.js +14 -0
- package/dist/esm/Theme/tokens/builders/planes.js +28 -0
- package/dist/esm/Theme/tokens/builders/skeletonShimmer.js +21 -0
- package/dist/esm/Theme/tokens/builders/surfaceRaised.js +16 -7
- package/dist/esm/Theme/tokens/builders/surfaceRungs.js +3 -1
- package/dist/esm/Theme/tokens/primitives/index.js +1 -1
- package/dist/esm/Theme/tokens/primitives/motion.js +1 -0
- package/dist/esm/Theme/tokens/primitives/shadows.js +54 -5
- package/dist/esm/Theme/tokens/primitives/typography.js +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +9 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -18,6 +18,12 @@ next major.
|
|
|
18
18
|
|
|
19
19
|
### Added
|
|
20
20
|
|
|
21
|
+
- **`Card variant="elevated"`**: borderless, `background[50]` lifted by `shadows.card`; declares a 0 border width so it
|
|
22
|
+
never inherits an outline parent's rule.
|
|
23
|
+
- **`bandOn`, `recessOn`, `cardRule`**: plane-step helpers that return the input unchanged in light and a visible step
|
|
24
|
+
off the dark plane a fill or rule sits on (`raisedRule` now matches `cardRule`'s weight).
|
|
25
|
+
- **`buildDarkPalette`** takes an optional `{ planes: "lifted" | "flat" }` and `buildSurfaceRaised` an optional list of
|
|
26
|
+
filled marks to keep at 3:1.
|
|
21
27
|
- **`formatDate` / `formatDateTime` / `formatDateRange`**: Intl-based date text, en-IN by default ("09 Oct 2026"),
|
|
22
28
|
with `locale`, `timeZone`, `year: "never"`, `time: "12h" | "24h"` and a `fallback` (default "—") for null or
|
|
23
29
|
invalid input instead of "Invalid Date". A bare `YYYY-MM-DD` is that calendar day in every zone; ranges write a
|
|
@@ -316,8 +322,8 @@ next major.
|
|
|
316
322
|
- **`Card` `padding` is no longer Chakra's style prop** — it is omitted from the type and now takes
|
|
317
323
|
the `CardPadding` steps. A consumer passing `padding={4}` gets a compile error; use `p` or `sx`.
|
|
318
324
|
Staged for the next major (see Breaking); consumer blast radius not measured.
|
|
319
|
-
- **`SideBar`
|
|
320
|
-
`speed
|
|
325
|
+
- **`SideBar` `collapseTransition` defaults to `{ speed: "base" }`** (200ms width and shadow, was 260ms).
|
|
326
|
+
Pass `{ speed: "slow" }` for the old pace.
|
|
321
327
|
- **`StageProgress variant="stepper"` renders an `ol` of `li`** (`StepperStageProps.asListItem`).
|
|
322
328
|
Visual layout is unchanged; selectors that expected a `div` list no longer match.
|
|
323
329
|
- **`PdfViewer` `pdfUrl` is optional** — pass exactly one of `pdfUrl` / `getBlob`. In `getBlob` mode
|
|
@@ -373,8 +379,75 @@ next major.
|
|
|
373
379
|
`aria-readonly`, and `m`/`mt`/`mb`/`ml`/`mr`/`mx`/`my` on the wrapper. `InputSwitch` is now a
|
|
374
380
|
genuine thin wrapper — no prop it previously accepted is silently dropped.
|
|
375
381
|
|
|
382
|
+
### Changed (visual)
|
|
383
|
+
|
|
384
|
+
- **Elevation follows Pebble, per mode.** `shadows.sm`/`base`/`md`/`lg` are the Pebble card-press/
|
|
385
|
+
card/float/dialog stacks, with new `card`, `float`, `dialog` and `sheet` role keys. Light shadows are
|
|
386
|
+
softer and wider; dark mode gets its own heavier black ramp, so overlays cast a visible shadow on a
|
|
387
|
+
dark canvas. `xs`, `xl`, `2xl`, `inner`, `none`, `darkLg` and the focus `outline` are unchanged.
|
|
388
|
+
- **`Menu` and `Popover` join the owned popup family:** radius `md` → `xl` (`RADIUS_ROLE.float`)
|
|
389
|
+
and shadow `sm` → `md` (float), like every other anchored popup. Their border stays.
|
|
390
|
+
- **`fonts.mono` is a real monospace stack** (`ui-monospace, SFMono-Regular, Menlo, Consolas,
|
|
391
|
+
monospace`). It was Inter, so code and keyboard shortcuts never aligned.
|
|
392
|
+
- **`Button` gray `ghost`/`outline` hover is visible.** Gray has no opacity ramp, so hover/active
|
|
393
|
+
take the list-row `active`/`selectedActive` steps (at least 1.15:1 on a card, all 9 brands x 2 modes)
|
|
394
|
+
instead of `gray.50` (1.04-1.08:1). `solid` and `gradient` hover no longer add a box-shadow; the
|
|
395
|
+
colour step carries hover.
|
|
396
|
+
- **`Toaster` status-icon pulse** animates a pseudo-element's transform and opacity (scale 1 to 1.5,
|
|
397
|
+
faded out by 70%, the same 900 ms one-shot) instead of `box-shadow`, so it no longer repaints every
|
|
398
|
+
frame. The icon chip background is the same tint composited opaque over the toast surface.
|
|
399
|
+
- **`Table` filter sidebar** opens on the 200 ms motion token (was 500 ms), does not animate on
|
|
400
|
+
mount, and is instant under reduced motion.
|
|
401
|
+
- **`FileUpload` image thumbnails are a keyboard-operable "Preview <file name>" button**: a new tab
|
|
402
|
+
stop with the library focus ring; Enter or Space opens the preview. Each image row now has two
|
|
403
|
+
buttons (Preview and remove), so a test that queries an unnamed `getByRole("button")` inside a row
|
|
404
|
+
must name the one it means.
|
|
405
|
+
- **`Menu` item highlight sits inside the menu.** A themed `MenuItem`/`MenuItemOption` is
|
|
406
|
+
`calc(100% - 2 * mx)` wide, so its hover/focus fill keeps the same 6px inset on both sides instead of
|
|
407
|
+
overhanging the menu's right edge by 6px. Menu size and row height are unchanged; a `MenuItem` given
|
|
408
|
+
its own `w`/`width` keeps that width.
|
|
409
|
+
- **`Skeleton` shimmer is one depth on every brand and mode**: 1.35:1 between its two colours (the
|
|
410
|
+
mobile library's `SKELETON_SHIMMER_CONTRAST`), was 1.34-1.58:1 in light and 1.93-1.99:1 in dark. The
|
|
411
|
+
end colour is `gray[300]`'s tint settled against `gray[100]`; dark skeletons pulse much more gently.
|
|
412
|
+
An explicit `startColor`/`endColor` still wins.
|
|
413
|
+
|
|
414
|
+
- **Motion comes from the tokens.** `SideBar`, `Notification`, `Toaster`, the Table settings sheet,
|
|
415
|
+
`ProfilePhotoViewer`, `TableToggle` and `StageProgress` take every duration and curve from the motion tokens
|
|
416
|
+
(colour fades 150ms, movement 200ms, enters on `MOTION_EASE_OUT`, exits on `MOTION_EASE_IN`). Most timings
|
|
417
|
+
move by under 60ms; the Table settings sheet goes from 400ms to 200ms. `Notification` cards no longer lift
|
|
418
|
+
2px on hover; the shadow still deepens.
|
|
419
|
+
- **`Button` (solid, outline, ghost) and `IconButton` scale to 0.98 while pressed** (`MOTION_PRESS_SCALE`).
|
|
420
|
+
Never when disabled or loading, nor under `prefers-reduced-motion`.
|
|
421
|
+
- **Dark planes carry the brand hue and separate by lift.** The dark canvas takes a faint brand tint and cards
|
|
422
|
+
(`background[50]`) sit one step (1.16:1) above it, with overlays (`surfaceRaised`) one step (1.15:1) above
|
|
423
|
+
the card; every filled mark keeps 3:1 on all three. Light mode is unchanged. A brand opts out with
|
|
424
|
+
`buildDarkPalette(light, { planes: "flat" })`. `meadow` and `rosewood` dark `accentText` move one rung
|
|
425
|
+
lighter so they clear AA on selected list rows.
|
|
426
|
+
- **`zinc`:** muted text in light mode is `#515157` (was `#27272a`, 14.9:1), settled under a new 8:1 muted
|
|
427
|
+
ceiling; zinc's dark card is no longer darker than its canvas.
|
|
428
|
+
- **A brand's primary never reads as danger.** `radiant`'s danger colour (`red` and `semantic.error`) is
|
|
429
|
+
crimson and `rosewood`'s primary rotates toward raspberry; a delta-E >= 10 gate in `brandIdentity.test.ts`
|
|
430
|
+
covers all 9 brands in both modes.
|
|
431
|
+
- **`Button` solid primary paints `resolveFilledSurface`.** Only `zinc` dark moves: the primary fill goes from `#52525b` with
|
|
432
|
+
white ink (2.5:1 on the canvas) to `#e4e4e7` with black ink, matching `resolveFilledSurface`, the fill every other filled surface already paints.
|
|
433
|
+
- **Dark mode: header strips, calendar off-days and in-card rules step visibly off the lifted planes.** Table header
|
|
434
|
+
strips (`CustomModulesTable`, `SignInActivityTable`), `DatePicker` weekly-off cells, and the rules inside cards and
|
|
435
|
+
dialogs (`Table`, `SettingRow`, `SettingsSection`, `StatCard`, `Drawer`, `Modal`, `ConfirmDialog` and the account
|
|
436
|
+
modals) now clear 1.15:1 (bands) and 1.31:1 (rules) off their plane. Light mode is unchanged.
|
|
437
|
+
- **`Card` defaults to `variant="elevated"`** (borderless, `background[50]` lifted by `shadows.card`). Pass
|
|
438
|
+
`variant="outline"` for a Card that frames a table or a list of rows. Measured blast radius: 22 library `<Card>`
|
|
439
|
+
sites with no variant flip (hrms 18, account 1, tickets 3); 305 with an explicit variant are unchanged. The
|
|
440
|
+
`SettingsSection` danger zone keeps its red frame by taking `variant="outline"`.
|
|
441
|
+
- **Light page canvas (`backgroundColor.base`) sits 1.09:1 below the card on all 9 brands**, so a borderless card keeps
|
|
442
|
+
its top edge (zinc and slate `#fafafa` to `#f5f5f5`, lavender `#fbfafd` to `#f5f4f8`). `main` and every other token
|
|
443
|
+
are unchanged.
|
|
444
|
+
|
|
376
445
|
### Fixed
|
|
377
446
|
|
|
447
|
+
- **`Table` settings sheet** fades in place instead of dropping in when the user prefers reduced motion.
|
|
448
|
+
- **`SearchSelect`**: the Select All and Add New rows are reachable from the keyboard. Arrow keys, Home and End walk
|
|
449
|
+
Select All, then the options, then Add New, and Enter runs them. Both are now `role="option"` rows, so a test that
|
|
450
|
+
counts `getAllByRole("option")` with either row shown sees one or two more.
|
|
378
451
|
- **Field helper text no longer leaves a dangling `<id>-helptext` in `aria-describedby`** when a field with an
|
|
379
452
|
explicit `id` sits inside a consumer `FormControl` (`TextInput` and every field rendering
|
|
380
453
|
`FieldMessage`/`HelperText`).
|
package/COMPONENT-GOTCHAS.md
CHANGED
|
@@ -215,7 +215,7 @@ and wires `aria-controls` to them. Pick by that, never by the picture. A screen
|
|
|
215
215
|
|
|
216
216
|
| Need | Component | Why not the others |
|
|
217
217
|
| --- | --- | --- |
|
|
218
|
-
| Generic
|
|
218
|
+
| Generic padded container (borderless by default; `variant="outline"` for a ruled one), no commerce semantics | `Card` | Layout wrapper with `header`/`footer` slots and a padded body — see gotcha below |
|
|
219
219
|
| Product tile for a grid, list or rail (photo, price, rating, swatches, quick add) | `ProductCard` | Takes the same `axes` / `variants` as `ProductDetails`; for a whole page use `ProductDetails` |
|
|
220
220
|
| A KPI figure with delta and sparkline | `StatCard` | Not a product or a container |
|
|
221
221
|
| Subscription/pricing-tier card (plans, billing cycle, feature list) | `PaymentCard` | Takes a `Plan` object, unrelated to `options`/`productImage` |
|
|
@@ -401,7 +401,7 @@ The wrapper is deliberately not a button; make the custom component a button, or
|
|
|
401
401
|
| `InputTextArea` / `FileUpload` / `TextInput` | Width 500px → 100% / `maxSizeKB` 5 → 5120 / no default "Placeholder" text | `width="500px"` / — (5 KB was a bug) / — |
|
|
402
402
|
| `DatePicker` (no `pickerType`) | Inference is case-sensitive: `MM` is month, `mm` minutes. `dd/MM/yyyy` was misread as date+time and showed time selects; it is now date-only | `pickerType="datetime"` |
|
|
403
403
|
| `EmptyState` | Title is an `h3`; image is decorative (`alt=""`, was the title) | `titleAs`, `imageAlt` |
|
|
404
|
-
| Theme `Badge` / `Card` / field labels | Badge: pill, no uppercase, default `sm`. Card: default variant `
|
|
404
|
+
| Theme `Badge` / `Card` / field labels | Badge: pill, no uppercase, default `sm`. Card: default variant `elevated` (borderless, `shadows.card`). Label colour `text[700]`; helper/error row 12px | `size`/`variant` props |
|
|
405
405
|
| `Header` | `position: sticky; top: 0`, z-index `sticky` (1100, was 1000); `rightSlot` mounts once, not per layout | — |
|
|
406
406
|
| `Table` | Radius `xl`; row height 32/40/52 by density; filter button is named "Filter {label}" (tests querying "Search" break); client pagination resets to page 1 when `data.length` changes | — |
|
|
407
407
|
| `KanbanBoard` | `height`/`maxH` props replace the clipping wrapper; `height="100%"` needs a parent with a definite height | — |
|
|
@@ -534,10 +534,19 @@ A popup opened inside another popup takes `zIndex="popoverNested"` (1510), never
|
|
|
534
534
|
|
|
535
535
|
### Your own overlay painted `background[50]` sinks into the dark canvas
|
|
536
536
|
|
|
537
|
-
In dark mode `background[50]`
|
|
538
|
-
|
|
539
|
-
step
|
|
540
|
-
`surfaceRaised` too, and a divider inside it `raisedRule(colors)`.
|
|
537
|
+
In dark mode `background[50]` is the card plane, one step above the canvas; an overlay painted with it
|
|
538
|
+
merges into the cards under it. Library dialogs, drawers, popovers and menus paint `colors.surfaceRaised`,
|
|
539
|
+
one step above the card in dark and identical `#ffffff` in light. A custom panel, popover or
|
|
540
|
+
`ModalContent bg=` should read `surfaceRaised` too, and a divider inside it `raisedRule(colors)`.
|
|
541
|
+
|
|
542
|
+
### Named fills nearly vanish on a dark card
|
|
543
|
+
|
|
544
|
+
In dark mode `backgroundColor.light`, `tertiary`, `medium` and `tableHeader` sit only 1.01-1.05:1 off
|
|
545
|
+
`background[50]`, `muted` 1.00-1.06:1 off `surfaceRaised`, and `boxborder[200]` 1.10-1.16:1 off a card and
|
|
546
|
+
1.00-1.06:1 off `surfaceRaised`. Never paint a named canvas fill or raw `boxborder[200]` on a card or overlay:
|
|
547
|
+
use `bandOn(fill, surface)` for a header strip, hover or selection tint, `recessOn(fill, surface)` for a shaded
|
|
548
|
+
or off cell, `cardRule(colors)` for a rule inside a card and `raisedRule(colors)` for a rule inside an overlay.
|
|
549
|
+
All four return the old value unchanged in light mode.
|
|
541
550
|
|
|
542
551
|
### `Drawer` / `Modal` / `ProfileCard` drop any child that isn't a named slot — use `portalChildren`
|
|
543
552
|
|
|
@@ -1873,6 +1882,16 @@ can outgrow the column.
|
|
|
1873
1882
|
to `null`, so put a Clear action beside it if one is needed.
|
|
1874
1883
|
- For free-text chips that are not email addresses use `TagInput`: same look as `MultiSelect`, any text, with
|
|
1875
1884
|
your own `validate`.
|
|
1885
|
+
- **Button press scale matches a real `:active` only.** A `MenuButton as={Button}` held open by Chakra's
|
|
1886
|
+
`data-active` keeps the darker pressed fill but does not stay at 0.98. A consumer `_active={{ transform }}`
|
|
1887
|
+
loses to the press rule while the pointer is down; use `variant="unstyled"` or an `sx` `&:active` with
|
|
1888
|
+
`!important`.
|
|
1889
|
+
|
|
1890
|
+
### `Card` is borderless by default (`elevated`)
|
|
1891
|
+
|
|
1892
|
+
A Card that frames a table or a list of rows needs `variant="outline"`. `borderColor` alone shows nothing, because
|
|
1893
|
+
the default border width is 0, and the outline rule is Chakra `gray[200]`, not `boxborder[200]`. Paint the page with
|
|
1894
|
+
`backgroundColor.base`: on `backgroundColor.main` a borderless card can be white on white.
|
|
1876
1895
|
|
|
1877
1896
|
### `Select` / `SearchSelect` multi rows have no checkbox role
|
|
1878
1897
|
|
package/DESIGN-GUIDE.md
CHANGED
|
@@ -12,15 +12,21 @@ tickets `layoutDensity.ts`), use it — it encodes these same rules. Otherwise t
|
|
|
12
12
|
|
|
13
13
|
Calm, dense, professional SaaS admin — Linear/Stripe-dashboard, not a landing page.
|
|
14
14
|
|
|
15
|
-
- **Hierarchy comes from type and whitespace, not boxes.** One
|
|
16
|
-
|
|
15
|
+
- **Hierarchy comes from type and whitespace, not boxes.** One surface per level. Never nest a
|
|
16
|
+
card inside a card; inside a card, separate with spacing or a `Divider`.
|
|
17
17
|
- **One primary action per view.** One `variant="solid"` button in the page header; everything
|
|
18
18
|
else `outline` or `ghost`. The only exception is a composer's Send button.
|
|
19
19
|
- **Left-aligned, scannable.** Titles and forms left-aligned; numbers right-aligned in tables.
|
|
20
20
|
- **Color means something.** Neutral by default; brand color for the primary action and selection;
|
|
21
21
|
semantic color only for status. No decorative gradients, no colored section backgrounds.
|
|
22
|
-
- **
|
|
23
|
-
|
|
22
|
+
- **Content cards float, data surfaces are ruled.** `Card` is borderless by default
|
|
23
|
+
(`variant="elevated"`: `background[50]` lifted by the soft `shadows.card`). Tables, filter bars,
|
|
24
|
+
list panes and fields keep their 1px `boxborder[200]` rule; a `Card` that frames a table or a
|
|
25
|
+
list of rows takes `variant="outline"`. Heavier shadows only on floating things (menus,
|
|
26
|
+
popovers, modals) and on hover of a card that is itself clickable.
|
|
27
|
+
- **Paint the page with `backgroundColor.base`.** In light mode it sits one step (1.09:1) below
|
|
28
|
+
the card, which is what gives a borderless card its top edge; `backgroundColor.main` is a
|
|
29
|
+
component surface and can be as white as the card.
|
|
24
30
|
|
|
25
31
|
## 2. Spacing (Chakra units, 1 = 4px)
|
|
26
32
|
|
|
@@ -228,7 +234,8 @@ hides its primary; when only one section is empty on a populated page, that sect
|
|
|
228
234
|
- Reaching for `SelectV2`, `SearchSelect`, `SelectSearch` in new work — all `@deprecated`.
|
|
229
235
|
One picker now: `Select` (`native={false}` for the themed, searchable, multi popup).
|
|
230
236
|
`Dropdown` is the exception — it is an action menu, not a picker, and is not replaced.
|
|
231
|
-
- A
|
|
237
|
+
- A card inside a card; a border on a content `Card` (it is borderless by default), or any resting
|
|
238
|
+
shadow heavier than `shadows.card`.
|
|
232
239
|
- Painting a whole table cell with a status color — use a `Tag` in the cell.
|
|
233
240
|
- Centered page titles, hero-sized headings, `size="lg"` buttons, or `size` props restating the default.
|
|
234
241
|
- More than one solid button in a view; a destructive action without `AlertDialog`.
|
|
@@ -5,18 +5,35 @@ const accentText_1 = require("../../Theme/tokens/builders/accentText");
|
|
|
5
5
|
const filledSurface_1 = require("../../Theme/tokens/builders/filledSurface");
|
|
6
6
|
const gradientInk_1 = require("../../Theme/tokens/builders/gradientInk");
|
|
7
7
|
const focusRing_styles_1 = require("../../Theme/chakra/focusRing.styles");
|
|
8
|
+
const rowStates_1 = require("../../Theme/tokens/builders/rowStates");
|
|
8
9
|
const motion_1 = require("../../Theme/chakra/motion");
|
|
9
10
|
const primitives_1 = require("../../Theme/tokens/primitives");
|
|
11
|
+
const BUTTON_TRANSITION = [
|
|
12
|
+
(0, primitives_1.transitionFor)(["background-color", "border-color", "color", "box-shadow", "filter"]),
|
|
13
|
+
(0, primitives_1.transitionFor)(["transform"], "fast", "out"),
|
|
14
|
+
].join(", ");
|
|
15
|
+
const PRESS = {
|
|
16
|
+
[motion_1.MOTION_OK_QUERY]: {
|
|
17
|
+
"&:active:not(:disabled):not([data-loading]):not([aria-disabled=true])": {
|
|
18
|
+
transform: `scale(${primitives_1.MOTION_PRESS_SCALE})`,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
};
|
|
10
22
|
const controlSize = (size) => {
|
|
11
23
|
const { height, fontSize, paddingX } = primitives_1.BUTTON_SIZES[size];
|
|
12
24
|
return { h: height, minW: height, fontSize, px: paddingX };
|
|
13
25
|
};
|
|
14
26
|
// NOTE: [500] alone measures ~4.2 on a dark canvas — resolved per-mode so outline/ghost/link text stays readable.
|
|
15
27
|
const onCanvasText = (theme, colorScheme) => (0, accentText_1.accentTextOnCanvas)(theme.colors[colorScheme], theme.colors.backgroundColor.main);
|
|
16
|
-
// NOTE: [50] alone measured ~1.04 (invisible) in both modes —
|
|
28
|
+
// NOTE: [50] alone measured ~1.04 (invisible) in both modes — gray borrows the row-state steps.
|
|
17
29
|
const onCanvasHoverBg = (theme, colorScheme, step) => {
|
|
18
30
|
const scale = theme.colors[colorScheme];
|
|
19
|
-
|
|
31
|
+
if ("opacity" in scale)
|
|
32
|
+
return scale.opacity[step];
|
|
33
|
+
if (colorScheme !== "gray")
|
|
34
|
+
return scale[50];
|
|
35
|
+
const rows = (0, rowStates_1.listRowBackgrounds)(theme.colors);
|
|
36
|
+
return step === 16 ? rows.active : rows.selectedActive;
|
|
20
37
|
};
|
|
21
38
|
const swatch = (theme, colorScheme) => theme.colors[colorScheme];
|
|
22
39
|
const buttonSolidRung = (theme, colorScheme) => (0, filledSurface_1.solidFillRung)(swatch(theme, colorScheme), theme.colors.white);
|
|
@@ -27,6 +44,21 @@ const darkerFill = (theme, colorScheme, step) => {
|
|
|
27
44
|
};
|
|
28
45
|
/** Label for the solid variant's filled bg — derived from THAT fill, since hover/active swap it. */
|
|
29
46
|
const labelFor = (theme, fill) => (0, filledSurface_1.labelOnFill)(fill, theme.colors.white, theme.colors.black);
|
|
47
|
+
const solidSurface = (theme, colorScheme) => {
|
|
48
|
+
if (colorScheme === "primary")
|
|
49
|
+
return (0, filledSurface_1.resolveFilledSurface)(theme.colors.primary, theme.colors);
|
|
50
|
+
const fill = theme.colors[colorScheme][buttonSolidRung(theme, colorScheme)];
|
|
51
|
+
const hoverFill = darkerFill(theme, colorScheme, 0);
|
|
52
|
+
const activeFill = darkerFill(theme, colorScheme, 1);
|
|
53
|
+
return {
|
|
54
|
+
fill,
|
|
55
|
+
color: labelFor(theme, fill),
|
|
56
|
+
hoverFill,
|
|
57
|
+
hoverColor: labelFor(theme, hoverFill),
|
|
58
|
+
activeFill,
|
|
59
|
+
activeColor: labelFor(theme, activeFill),
|
|
60
|
+
};
|
|
61
|
+
};
|
|
30
62
|
// NOTE: replaces Chakra's stock ring, which failed WCAG 1.4.11 on every brand — gated by focusRing.test.ts.
|
|
31
63
|
const focusRing = (theme) => (0, focusRing_styles_1.focusVisibleStyles)(theme.colors);
|
|
32
64
|
exports.Button = {
|
|
@@ -35,7 +67,7 @@ exports.Button = {
|
|
|
35
67
|
baseStyle: ({ theme }) => ({
|
|
36
68
|
borderRadius: "lg",
|
|
37
69
|
fontWeight: 500,
|
|
38
|
-
transition:
|
|
70
|
+
transition: BUTTON_TRANSITION,
|
|
39
71
|
...(0, motion_1.reducedMotionSx)(),
|
|
40
72
|
_disabled: {
|
|
41
73
|
opacity: 0.6,
|
|
@@ -45,35 +77,32 @@ exports.Button = {
|
|
|
45
77
|
}),
|
|
46
78
|
variants: {
|
|
47
79
|
solid: ({ theme, colorScheme = "primary" }) => {
|
|
48
|
-
const
|
|
49
|
-
const hoverFill = darkerFill(theme, colorScheme, 0);
|
|
50
|
-
const activeFill = darkerFill(theme, colorScheme, 1);
|
|
51
|
-
const hoverLabel = labelFor(theme, hoverFill);
|
|
80
|
+
const s = solidSurface(theme, colorScheme);
|
|
52
81
|
return {
|
|
53
|
-
bg: fill,
|
|
54
|
-
color:
|
|
82
|
+
bg: s.fill,
|
|
83
|
+
color: s.color,
|
|
55
84
|
_hover: {
|
|
56
|
-
bg: hoverFill,
|
|
57
|
-
color:
|
|
58
|
-
boxShadow: "sm",
|
|
85
|
+
bg: s.hoverFill,
|
|
86
|
+
color: s.hoverColor,
|
|
59
87
|
_disabled: {
|
|
60
|
-
bg: hoverFill, // keep hover color on loading
|
|
61
|
-
color:
|
|
88
|
+
bg: s.hoverFill, // keep hover color on loading
|
|
89
|
+
color: s.hoverColor,
|
|
62
90
|
},
|
|
63
91
|
},
|
|
64
92
|
_active: {
|
|
65
|
-
bg: activeFill,
|
|
66
|
-
color:
|
|
93
|
+
bg: s.activeFill,
|
|
94
|
+
color: s.activeColor,
|
|
67
95
|
boxShadow: "none",
|
|
68
96
|
},
|
|
69
97
|
_loading: {
|
|
70
|
-
bg: hoverFill, // keep hover color while loading
|
|
71
|
-
color:
|
|
98
|
+
bg: s.hoverFill, // keep hover color while loading
|
|
99
|
+
color: s.hoverColor,
|
|
72
100
|
_hover: {
|
|
73
|
-
bg: hoverFill,
|
|
74
|
-
color:
|
|
101
|
+
bg: s.hoverFill,
|
|
102
|
+
color: s.hoverColor,
|
|
75
103
|
},
|
|
76
104
|
},
|
|
105
|
+
...PRESS,
|
|
77
106
|
...focusRing(theme),
|
|
78
107
|
};
|
|
79
108
|
},
|
|
@@ -94,6 +123,7 @@ exports.Button = {
|
|
|
94
123
|
_loading: {
|
|
95
124
|
color: ink,
|
|
96
125
|
},
|
|
126
|
+
...PRESS,
|
|
97
127
|
...focusRing(theme),
|
|
98
128
|
};
|
|
99
129
|
},
|
|
@@ -107,6 +137,7 @@ exports.Button = {
|
|
|
107
137
|
_active: {
|
|
108
138
|
bg: onCanvasHoverBg(theme, colorScheme, 24),
|
|
109
139
|
},
|
|
140
|
+
...PRESS,
|
|
110
141
|
...focusRing(theme),
|
|
111
142
|
}),
|
|
112
143
|
link: ({ theme, colorScheme = "primary" }) => ({
|
|
@@ -143,7 +174,6 @@ exports.Button = {
|
|
|
143
174
|
_hover: {
|
|
144
175
|
bgImage: bg,
|
|
145
176
|
filter: "brightness(0.92)",
|
|
146
|
-
boxShadow: "md",
|
|
147
177
|
_disabled: { bgImage: bg, filter: "none" },
|
|
148
178
|
},
|
|
149
179
|
_active: {
|
|
@@ -8,14 +8,14 @@ type DeadDividerProps = {
|
|
|
8
8
|
};
|
|
9
9
|
/** Padding steps: "none" flush, "2xs" 0.375rem, "xs" 0.75rem all round, "sm" / "md" / "lg" match `size`. */
|
|
10
10
|
export type CardPadding = "none" | "2xs" | "xs" | "sm" | "md" | "lg";
|
|
11
|
-
/** Themed
|
|
11
|
+
/** Themed card surface (outline rule or borderless elevated) with optional header/footer slots; direction/align/justify apply to the body. */
|
|
12
12
|
export type CardProps = Omit<ChakraCardProps, "children" | "variant" | "size" | "color" | "colorScheme" | "direction" | "align" | "justify" | "padding"> & DeadDividerProps & {
|
|
13
13
|
/** Rendered in CardHeader (semibold header ink) only when truthy. */
|
|
14
14
|
header?: React.ReactNode;
|
|
15
15
|
/** Rendered in CardFooter only when truthy. */
|
|
16
16
|
footer?: React.ReactNode;
|
|
17
17
|
children: React.ReactNode;
|
|
18
|
-
/**
|
|
18
|
+
/** "elevated" (default): borderless, lifted by `shadows.card`. "outline": 1px rule, no shadow, for tables and row lists. */
|
|
19
19
|
variant?: "elevated" | "outline" | "filled" | "unstyled";
|
|
20
20
|
/** Padding scale for header/body/footer; defaults to "md". */
|
|
21
21
|
size?: "sm" | "md" | "lg";
|
|
@@ -8,6 +8,7 @@ const react_1 = require("react");
|
|
|
8
8
|
const react_2 = require("@chakra-ui/react");
|
|
9
9
|
const lucide_react_1 = require("lucide-react");
|
|
10
10
|
const useCustomTheme_1 = require("../../Theme/useCustomTheme");
|
|
11
|
+
const surfaceRaised_1 = require("../../Theme/tokens/builders/surfaceRaised");
|
|
11
12
|
const Button_1 = __importDefault(require("../Button/Button"));
|
|
12
13
|
const TextInput_1 = __importDefault(require("../Input/TextInput"));
|
|
13
14
|
const ConfirmDialog = ({ isOpen, onClose, onConfirm, title, children, icon, iconBg, iconColor, tone = "destructive", cancelLabel = "Cancel", confirmLabel = "Confirm", confirmIcon, isConfirmLoading = false, disableCancelWhilePending = true, confirmationText, confirmationLabel, bodyLayout = "flush", bodySpacing = 4, actionsPt = 0, focusCancelOnOpen = true, isCentered = true, closeOnEsc, closeOnOverlayClick, }) => {
|
|
@@ -18,6 +19,6 @@ const ConfirmDialog = ({ isOpen, onClose, onConfirm, title, children, icon, icon
|
|
|
18
19
|
const isConfirmDisabled = isConfirmLoading || (requiresTypedConfirmation && typedText !== confirmationText);
|
|
19
20
|
const actions = ((0, jsx_runtime_1.jsxs)(react_2.HStack, { justifyContent: "flex-end", spacing: 3, pt: actionsPt, children: [(0, jsx_runtime_1.jsx)(Button_1.default, { ref: cancelRef, label: cancelLabel, onClick: onClose, variant: "outline", colorScheme: "gray", size: "sm", isDisabled: disableCancelWhilePending && isConfirmLoading }), (0, jsx_runtime_1.jsx)(Button_1.default, { label: confirmLabel, onClick: onConfirm, colorScheme: tone === "destructive" ? "red" : "primary", size: "sm", isLoading: isConfirmLoading, isDisabled: isConfirmDisabled, leftIcon: confirmIcon })] }));
|
|
20
21
|
const body = requiresTypedConfirmation ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [children, (0, jsx_runtime_1.jsx)(TextInput_1.default, { label: confirmationLabel, value: typedText, onChange: (event) => setTypedText(event.target.value) })] })) : (children);
|
|
21
|
-
return ((0, jsx_runtime_1.jsxs)(react_2.Modal, { isOpen: isOpen, onClose: onClose, isCentered: isCentered, closeOnEsc: closeOnEsc, closeOnOverlayClick: closeOnOverlayClick, initialFocusRef: focusCancelOnOpen ? cancelRef : undefined, children: [(0, jsx_runtime_1.jsx)(react_2.ModalOverlay, { backdropFilter: "blur(4px)" }), (0, jsx_runtime_1.jsxs)(react_2.ModalContent, { bg: colors.surfaceRaised, borderRadius: "xl", overflow: "hidden", children: [(0, jsx_runtime_1.jsxs)(react_2.ModalHeader, { borderBottom: "1px solid", borderColor: colors
|
|
22
|
+
return ((0, jsx_runtime_1.jsxs)(react_2.Modal, { isOpen: isOpen, onClose: onClose, isCentered: isCentered, closeOnEsc: closeOnEsc, closeOnOverlayClick: closeOnOverlayClick, initialFocusRef: focusCancelOnOpen ? cancelRef : undefined, children: [(0, jsx_runtime_1.jsx)(react_2.ModalOverlay, { backdropFilter: "blur(4px)" }), (0, jsx_runtime_1.jsxs)(react_2.ModalContent, { bg: colors.surfaceRaised, borderRadius: "xl", overflow: "hidden", children: [(0, jsx_runtime_1.jsxs)(react_2.ModalHeader, { borderBottom: "1px solid", borderColor: (0, surfaceRaised_1.raisedRule)(colors), display: "flex", alignItems: "center", gap: 3, children: [(0, jsx_runtime_1.jsx)(react_2.Flex, { align: "center", justify: "center", boxSize: "36px", borderRadius: "full", bg: iconBg, color: iconColor, children: icon !== null && icon !== void 0 ? icon : (0, jsx_runtime_1.jsx)(lucide_react_1.AlertTriangle, { size: 18 }) }), (0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "1.05rem", fontWeight: 600, children: title })] }), (0, jsx_runtime_1.jsx)(react_2.ModalCloseButton, {}), (0, jsx_runtime_1.jsx)(react_2.ModalBody, { py: 6, children: bodyLayout === "stack" ? ((0, jsx_runtime_1.jsxs)(react_2.VStack, { spacing: bodySpacing, align: "stretch", children: [body, actions] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [body, actions] })) })] })] }));
|
|
22
23
|
};
|
|
23
24
|
exports.default = ConfirmDialog;
|
|
@@ -8,6 +8,7 @@ const react_1 = require("react");
|
|
|
8
8
|
const react_2 = require("@chakra-ui/react");
|
|
9
9
|
const lucide_react_1 = require("lucide-react");
|
|
10
10
|
const useCustomTheme_1 = require("../../Theme/useCustomTheme");
|
|
11
|
+
const planeStep_1 = require("../../Theme/tokens/builders/planeStep");
|
|
11
12
|
const Button_1 = __importDefault(require("../Button/Button"));
|
|
12
13
|
const EmptyState_1 = __importDefault(require("../EmptyState/EmptyState"));
|
|
13
14
|
const EditModuleModal_1 = __importDefault(require("./EditModuleModal"));
|
|
@@ -34,20 +35,21 @@ const CustomModulesTable = ({ modules, isLoading = false, isUpdating = false, is
|
|
|
34
35
|
const labels = (0, react_1.useMemo)(() => ({ ...DEFAULT_LABELS, ...labelOverrides }), [labelOverrides]);
|
|
35
36
|
const [editTarget, setEditTarget] = (0, react_1.useState)(null);
|
|
36
37
|
const [deleteTarget, setDeleteTarget] = (0, react_1.useState)(null);
|
|
37
|
-
const
|
|
38
|
+
const edge = colors.boxborder[200];
|
|
38
39
|
const surface = colors.background[50];
|
|
40
|
+
const rule = (0, planeStep_1.cardRule)(colors);
|
|
39
41
|
const muted = colors.textMuted;
|
|
40
42
|
const heading = colors.text[800];
|
|
41
|
-
const headBg = colors.backgroundColor.tableHeader;
|
|
43
|
+
const headBg = (0, planeStep_1.bandOn)(colors.backgroundColor.tableHeader, surface);
|
|
42
44
|
const thStyle = {
|
|
43
45
|
fontSize: "0.7rem",
|
|
44
46
|
textTransform: "uppercase",
|
|
45
47
|
letterSpacing: "0.04em",
|
|
46
48
|
color: muted,
|
|
47
|
-
borderColor:
|
|
49
|
+
borderColor: rule,
|
|
48
50
|
py: 3,
|
|
49
51
|
};
|
|
50
|
-
return ((0, jsx_runtime_1.jsxs)(react_2.Box, { backgroundColor: surface, borderRadius: "xl", border: "1px solid", borderColor:
|
|
52
|
+
return ((0, jsx_runtime_1.jsxs)(react_2.Box, { backgroundColor: surface, borderRadius: "xl", border: "1px solid", borderColor: edge, boxShadow: "sm", overflow: "hidden", children: [(0, jsx_runtime_1.jsx)(react_2.Flex, { px: 4, py: 3, borderBottom: "1px solid", borderColor: rule, alignItems: "center", children: (0, jsx_runtime_1.jsx)(react_2.Heading, { size: "sm", fontWeight: 600, color: heading, children: labels.title }) }), (0, jsx_runtime_1.jsx)(react_2.Box, { overflowX: "auto", children: isLoading ? ((0, jsx_runtime_1.jsx)(react_2.VStack, { spacing: 3, p: 4, align: "stretch", children: Array.from({ length: 4 }).map((_, idx) => ((0, jsx_runtime_1.jsx)(react_2.Skeleton, { height: "18px", borderRadius: "md", startColor: colors.gray[100], endColor: colors.gray[400] }, idx))) })) : modules.length === 0 ? ((0, jsx_runtime_1.jsx)(EmptyState_1.default, { icon: lucide_react_1.Boxes, title: labels.noModules, size: "sm", minH: "180px" })) : ((0, jsx_runtime_1.jsxs)(react_2.Table, { variant: "simple", size: "sm", children: [(0, jsx_runtime_1.jsx)(react_2.Thead, { bg: headBg, children: (0, jsx_runtime_1.jsxs)(react_2.Tr, { children: [(0, jsx_runtime_1.jsx)(react_2.Th, { ...thStyle, children: labels.moduleName }), (0, jsx_runtime_1.jsx)(react_2.Th, { ...thStyle, children: labels.moduleOwner }), (0, jsx_runtime_1.jsx)(react_2.Th, { ...thStyle, textAlign: "right", children: labels.action })] }) }), (0, jsx_runtime_1.jsx)(react_2.Tbody, { children: modules.map((item) => ((0, jsx_runtime_1.jsxs)(react_2.Tr, { _hover: { bg: headBg }, transition: "background 0.15s ease", children: [(0, jsx_runtime_1.jsx)(react_2.Td, { borderColor: rule, fontSize: "sm", fontWeight: 500, color: heading, maxW: "220px", children: (0, jsx_runtime_1.jsx)(react_2.Tooltip, { label: item.moduleName, hasArrow: true, openDelay: 400, children: (0, jsx_runtime_1.jsx)(react_2.Text, { noOfLines: 1, children: item.moduleName }) }) }), (0, jsx_runtime_1.jsx)(react_2.Td, { borderColor: rule, fontSize: "sm", color: muted, children: item.ownerLabel || "—" }), (0, jsx_runtime_1.jsx)(react_2.Td, { borderColor: rule, children: (0, jsx_runtime_1.jsxs)(react_2.HStack, { spacing: 2, justifyContent: "flex-end", children: [(0, jsx_runtime_1.jsx)(Button_1.default, { size: "xs", variant: "outline", colorScheme: "primary", leftIcon: (0, jsx_runtime_1.jsx)(lucide_react_1.Pencil, { size: 13 }), label: labels.edit, onClick: () => setEditTarget(item) }), (0, jsx_runtime_1.jsx)(Button_1.default, { size: "xs", variant: "outline", colorScheme: "red", leftIcon: (0, jsx_runtime_1.jsx)(lucide_react_1.Trash2, { size: 13 }), label: labels.delete, onClick: () => setDeleteTarget(item) })] }) })] }, item.module_id))) })] })) }), (0, jsx_runtime_1.jsx)(EditModuleModal_1.default, { isOpen: editTarget !== null, onClose: () => setEditTarget(null), initialName: (_a = editTarget === null || editTarget === void 0 ? void 0 : editTarget.moduleName) !== null && _a !== void 0 ? _a : "", isLoading: isUpdating, onSubmit: async (name) => {
|
|
51
53
|
if (editTarget) {
|
|
52
54
|
await (onUpdateModule === null || onUpdateModule === void 0 ? void 0 : onUpdateModule({
|
|
53
55
|
moduleId: editTarget.module_id,
|
|
@@ -7,6 +7,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
7
7
|
const react_1 = require("react");
|
|
8
8
|
const react_2 = require("@chakra-ui/react");
|
|
9
9
|
const useCustomTheme_1 = require("../../Theme/useCustomTheme");
|
|
10
|
+
const surfaceRaised_1 = require("../../Theme/tokens/builders/surfaceRaised");
|
|
10
11
|
const Button_1 = __importDefault(require("../Button/Button"));
|
|
11
12
|
const EditModuleModal = ({ isOpen, onClose, initialName, isLoading, onSubmit, labels, }) => {
|
|
12
13
|
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
@@ -15,7 +16,7 @@ const EditModuleModal = ({ isOpen, onClose, initialName, isLoading, onSubmit, la
|
|
|
15
16
|
if (isOpen)
|
|
16
17
|
setName(initialName);
|
|
17
18
|
}, [isOpen, initialName]);
|
|
18
|
-
return ((0, jsx_runtime_1.jsxs)(react_2.Modal, { isOpen: isOpen, onClose: onClose, isCentered: true, children: [(0, jsx_runtime_1.jsx)(react_2.ModalOverlay, { backdropFilter: "blur(4px)" }), (0, jsx_runtime_1.jsxs)(react_2.ModalContent, { borderRadius: "xl", overflow: "hidden", bg: colors.surfaceRaised, children: [(0, jsx_runtime_1.jsx)(react_2.ModalHeader, { borderBottom: "1px solid", borderColor: colors
|
|
19
|
+
return ((0, jsx_runtime_1.jsxs)(react_2.Modal, { isOpen: isOpen, onClose: onClose, isCentered: true, children: [(0, jsx_runtime_1.jsx)(react_2.ModalOverlay, { backdropFilter: "blur(4px)" }), (0, jsx_runtime_1.jsxs)(react_2.ModalContent, { borderRadius: "xl", overflow: "hidden", bg: colors.surfaceRaised, children: [(0, jsx_runtime_1.jsx)(react_2.ModalHeader, { borderBottom: "1px solid", borderColor: (0, surfaceRaised_1.raisedRule)(colors), fontSize: "1.05rem", fontWeight: 600, children: labels.editModuleTitle }), (0, jsx_runtime_1.jsx)(react_2.ModalCloseButton, {}), (0, jsx_runtime_1.jsxs)(react_2.ModalBody, { py: 6, children: [(0, jsx_runtime_1.jsx)(react_2.Input, { value: name, onChange: (e) => setName(e.target.value), placeholder: labels.moduleNamePlaceholder, "aria-label": labels.moduleNamePlaceholder,
|
|
19
20
|
// NOTE: [200] is the decorative divider rung — a real control's outline needs 1.4.11's 3:1, from [800].
|
|
20
21
|
borderColor: colors.boxborder[500], mb: 5 }), (0, jsx_runtime_1.jsxs)(react_2.HStack, { justifyContent: "flex-end", spacing: 3, children: [(0, jsx_runtime_1.jsx)(Button_1.default, { label: labels.cancel, onClick: onClose, variant: "outline", colorScheme: "gray", size: "sm" }), (0, jsx_runtime_1.jsx)(Button_1.default, { label: labels.update, onClick: () => onSubmit(name.trim()), colorScheme: "primary", size: "sm", isLoading: isLoading, isDisabled: !name.trim() })] })] })] })] }));
|
|
21
22
|
};
|
|
@@ -49,6 +49,7 @@ const useFieldIds_1 = require("../Common/useFieldIds");
|
|
|
49
49
|
const pickerField_1 = require("./pickerField");
|
|
50
50
|
const CalendarPanel_1 = __importDefault(require("./CalendarPanel"));
|
|
51
51
|
const useCustomTheme_1 = require("../../Theme/useCustomTheme");
|
|
52
|
+
const surfaceRaised_1 = require("../../Theme/tokens/builders/surfaceRaised");
|
|
52
53
|
const controlSizes_1 = require("../../Theme/tokens/primitives/controlSizes");
|
|
53
54
|
const textInputIconSize_1 = require("../Input/textInputIconSize");
|
|
54
55
|
const TimePicker_1 = __importDefault(require("./TimePicker"));
|
|
@@ -264,7 +265,7 @@ exports.RangeDatePicker = (0, react_1.forwardRef)(function RangeDatePicker(props
|
|
|
264
265
|
return;
|
|
265
266
|
}
|
|
266
267
|
setTempRangeEnd(setTimeFrom(endTimeBaseDate, t));
|
|
267
|
-
}, dateFormat: timePickerFormat, isDisabled: disabled || !tempRangeEnd, size: sizeKey }))] })] })), (0, jsx_runtime_1.jsxs)(react_2.Box, { display: "flex", justifyContent: "space-between", alignItems: "center", mt: 3, pt: 3, borderTop: "1px solid", borderColor: theme.colors
|
|
268
|
+
}, dateFormat: timePickerFormat, isDisabled: disabled || !tempRangeEnd, size: sizeKey }))] })] })), (0, jsx_runtime_1.jsxs)(react_2.Box, { display: "flex", justifyContent: "space-between", alignItems: "center", mt: 3, pt: 3, borderTop: "1px solid", borderColor: (0, surfaceRaised_1.raisedRule)(theme.colors), children: [(0, jsx_runtime_1.jsx)(Button_1.default, { size: "sm", variant: "ghost", colorScheme: "gray", onClick: handleClear, children: "Clear" }), (0, jsx_runtime_1.jsx)(Button_1.default, { size: "sm", variant: "gradient", onClick: requestClose, children: "Apply" })] })] }) }) })] }), (0, jsx_runtime_1.jsx)(FieldMessage_1.default, { error: error, errorMessage: errorMessage, helperText: helperText, helperId: ids.helperId, errorId: ids.errorId })] }));
|
|
268
269
|
});
|
|
269
270
|
exports.RangeDatePicker.displayName = "RangeDatePicker";
|
|
270
271
|
exports.default = exports.RangeDatePicker;
|
|
@@ -44,6 +44,7 @@ const date_fns_1 = require("date-fns");
|
|
|
44
44
|
const lucide_react_1 = require("lucide-react");
|
|
45
45
|
const Button_1 = __importDefault(require("../Button/Button"));
|
|
46
46
|
const useCustomTheme_1 = require("../../Theme/useCustomTheme");
|
|
47
|
+
const surfaceRaised_1 = require("../../Theme/tokens/builders/surfaceRaised");
|
|
47
48
|
const controlSizes_1 = require("../../Theme/tokens/primitives/controlSizes");
|
|
48
49
|
const textInputIconSize_1 = require("../Input/textInputIconSize");
|
|
49
50
|
const DatePickerProps_1 = require("./DatePickerProps");
|
|
@@ -1026,7 +1027,7 @@ function SingleDatePickerInner(props, ref) {
|
|
|
1026
1027
|
setTempDate(updatedDate);
|
|
1027
1028
|
setInputValue((0, date_fns_1.format)(updatedDate, resolvedDateFormat));
|
|
1028
1029
|
setIsTyping(false);
|
|
1029
|
-
}, isDisabled: disabled })) })), (0, jsx_runtime_1.jsxs)(react_2.Box, { display: "flex", justifyContent: "space-between", alignItems: "center", mt: 3, pt: 3, borderTop: "1px solid", borderColor: theme.colors
|
|
1030
|
+
}, isDisabled: disabled })) })), (0, jsx_runtime_1.jsxs)(react_2.Box, { display: "flex", justifyContent: "space-between", alignItems: "center", mt: 3, pt: 3, borderTop: "1px solid", borderColor: (0, surfaceRaised_1.raisedRule)(theme.colors), children: [(0, jsx_runtime_1.jsx)(Button_1.default, { size: "sm", variant: "ghost", colorScheme: "gray", onClick: () => {
|
|
1030
1031
|
setTempDate(null);
|
|
1031
1032
|
requestClose(null);
|
|
1032
1033
|
}, children: "Clear" }), (0, jsx_runtime_1.jsx)(Button_1.default, { size: "sm", variant: "gradient", onClick: () => requestClose(), children: "Apply" })] })] }) }) })] }), (0, jsx_runtime_1.jsx)(FieldMessage_1.default, { error: error, errorMessage: errorMessage, helperText: helperText, helperId: ids.helperId, errorId: ids.errorId })] }));
|
|
@@ -52,6 +52,7 @@ const TimePickerInput_1 = require("./TimePickerInput");
|
|
|
52
52
|
const PickerPortal_1 = __importStar(require("./PickerPortal"));
|
|
53
53
|
const useExclusiveOverlay_1 = require("../../Hooks/useExclusiveOverlay");
|
|
54
54
|
const useCustomTheme_1 = require("../../Theme/useCustomTheme");
|
|
55
|
+
const surfaceRaised_1 = require("../../Theme/tokens/builders/surfaceRaised");
|
|
55
56
|
const controlSizes_1 = require("../../Theme/tokens/primitives/controlSizes");
|
|
56
57
|
const formatToPlaceholder = (formatStr) => formatStr.replace(/h{1,2}/gi, "HH").replace(/m{1,2}/gi, "mm").replace(/a{1,2}/gi, "AM");
|
|
57
58
|
function TimeOnlyPickerInner(props, ref) {
|
|
@@ -138,7 +139,7 @@ function TimeOnlyPickerInner(props, ref) {
|
|
|
138
139
|
openPicker();
|
|
139
140
|
}, error: error, size: sizeKey }) }) }) }), (0, jsx_runtime_1.jsx)(PickerPortal_1.default, { isMounted: pickerPortal.isMounted, children: (0, jsx_runtime_1.jsx)(react_2.PopoverContent, { width: "auto", p: 4, ref: popoverRef, boxShadow: "lg", borderRadius: "xl", bg: theme.colors.surfaceRaised, children: (0, jsx_runtime_1.jsxs)(react_2.PopoverBody, { children: [(0, jsx_runtime_1.jsx)(TimePicker_1.default, { date: resolvedTempDate, dateFormat: dateFormat, onChange: (updatedDate) => {
|
|
140
141
|
handleTimePickerChange(updatedDate);
|
|
141
|
-
} }), (0, jsx_runtime_1.jsxs)(react_2.Box, { display: "flex", justifyContent: "space-between", mt: 4, pt: 4, borderTop: "1px solid", borderColor: theme.colors
|
|
142
|
+
} }), (0, jsx_runtime_1.jsxs)(react_2.Box, { display: "flex", justifyContent: "space-between", mt: 4, pt: 4, borderTop: "1px solid", borderColor: (0, surfaceRaised_1.raisedRule)(theme.colors), children: [(0, jsx_runtime_1.jsx)(react_2.Button, { size: "sm", variant: "ghost", onClick: handleClear, children: "Clear" }), (0, jsx_runtime_1.jsx)(react_2.Button, { size: "sm", colorScheme: "primary", onClick: handleOk, children: "OK" })] })] }) }) })] }), (0, jsx_runtime_1.jsx)(FieldMessage_1.default, { error: error, errorMessage: errorMessage, helperText: helperText, helperId: ids.helperId, errorId: ids.errorId })] }));
|
|
142
143
|
}
|
|
143
144
|
exports.TimeOnlyPicker = (0, react_1.forwardRef)(TimeOnlyPickerInner);
|
|
144
145
|
exports.TimeOnlyPicker.displayName = "TimeOnlyPicker";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.dayAccessibleName = exports.describeDayStates = exports.dayStateClassName = exports.DAY_CLASS = exports.resolveDayStateVisual = exports.isDayStateKey = exports.DAY_STATE_KEYS = void 0;
|
|
4
|
+
const planeStep_1 = require("../../Theme/tokens/builders/planeStep");
|
|
4
5
|
// Ascending precedence — when a day carries several keys, a later one's visual overrides an earlier one's.
|
|
5
6
|
exports.DAY_STATE_KEYS = [
|
|
6
7
|
"weekly-off",
|
|
@@ -12,7 +13,7 @@ exports.DAY_STATE_KEYS = [
|
|
|
12
13
|
// NOTE: token roles per THEME-CONTRACT.md, not raw rungs — e.g. holiday uses semanticText, never semantic[500].
|
|
13
14
|
const VISUALS = {
|
|
14
15
|
"weekly-off": (colors) => ({
|
|
15
|
-
cellBg: colors.backgroundColor.muted,
|
|
16
|
+
cellBg: (0, planeStep_1.recessOn)(colors.backgroundColor.muted, colors.surfaceRaised),
|
|
16
17
|
color: colors.textMuted,
|
|
17
18
|
}),
|
|
18
19
|
holiday: (colors) => ({
|
|
@@ -8,6 +8,7 @@ exports.default = Drawer;
|
|
|
8
8
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
9
9
|
const react_1 = __importDefault(require("react"));
|
|
10
10
|
const useCustomTheme_1 = require("../../Theme/useCustomTheme");
|
|
11
|
+
const surfaceRaised_1 = require("../../Theme/tokens/builders/surfaceRaised");
|
|
11
12
|
const warnDroppedSlotChildren_1 = require("../Modal/warnDroppedSlotChildren");
|
|
12
13
|
const react_2 = require("@chakra-ui/react");
|
|
13
14
|
const DrawerHeader = ({ children }) => {
|
|
@@ -45,5 +46,5 @@ function Drawer({ isOpen, onClose, placement = "right", size = "xl", id, variant
|
|
|
45
46
|
const bodySlot = findSlot(children, exports.DrawerBody);
|
|
46
47
|
const footerSlot = findSlot(children, exports.DrawerFooter);
|
|
47
48
|
(0, warnDroppedSlotChildren_1.warnDroppedSlotChildren)("Drawer", children, [exports.DrawerHeader, exports.DrawerBody, exports.DrawerFooter]);
|
|
48
|
-
return ((0, jsx_runtime_1.jsxs)(react_2.Drawer, { isOpen: isOpen, placement: placement, onClose: onClose, size: size, variant: (_a = variant !== null && variant !== void 0 ? variant : vaiant) !== null && _a !== void 0 ? _a : "solid", id: id, initialFocusRef: initialFocusRef, finalFocusRef: finalFocusRef, closeOnOverlayClick: closeOnOverlayClick, closeOnEsc: closeOnEsc, children: [(0, jsx_runtime_1.jsx)(react_2.DrawerOverlay, {}), (0, jsx_runtime_1.jsxs)(react_2.DrawerContent, { ...contentProps, children: [!hideCloseButton && (0, jsx_runtime_1.jsx)(react_2.DrawerCloseButton, {}), headerSlot && ((0, jsx_runtime_1.jsx)(react_2.DrawerHeader, { borderBottomWidth: "1px", borderColor: colors
|
|
49
|
+
return ((0, jsx_runtime_1.jsxs)(react_2.Drawer, { isOpen: isOpen, placement: placement, onClose: onClose, size: size, variant: (_a = variant !== null && variant !== void 0 ? variant : vaiant) !== null && _a !== void 0 ? _a : "solid", id: id, initialFocusRef: initialFocusRef, finalFocusRef: finalFocusRef, closeOnOverlayClick: closeOnOverlayClick, closeOnEsc: closeOnEsc, children: [(0, jsx_runtime_1.jsx)(react_2.DrawerOverlay, {}), (0, jsx_runtime_1.jsxs)(react_2.DrawerContent, { ...contentProps, children: [!hideCloseButton && (0, jsx_runtime_1.jsx)(react_2.DrawerCloseButton, {}), headerSlot && ((0, jsx_runtime_1.jsx)(react_2.DrawerHeader, { borderBottomWidth: "1px", borderColor: (0, surfaceRaised_1.raisedRule)(colors), ...headerSlot.props, children: headerSlot })), (0, jsx_runtime_1.jsx)(react_2.DrawerBody, { ...((_b = bodySlot === null || bodySlot === void 0 ? void 0 : bodySlot.props) !== null && _b !== void 0 ? _b : {}), children: bodySlot }), footerSlot && ((0, jsx_runtime_1.jsx)(react_2.DrawerFooter, { borderTopWidth: "1px", borderColor: (0, surfaceRaised_1.raisedRule)(colors), ...footerSlot.props, children: footerSlot })), portalChildren] })] }));
|
|
49
50
|
}
|
|
@@ -5,6 +5,7 @@ const react_1 = require("react");
|
|
|
5
5
|
const react_2 = require("@chakra-ui/react");
|
|
6
6
|
const framer_motion_1 = require("framer-motion");
|
|
7
7
|
const useCustomTheme_1 = require("../../Theme/useCustomTheme");
|
|
8
|
+
const surfaceRaised_1 = require("../../Theme/tokens/builders/surfaceRaised");
|
|
8
9
|
const scrollbar_1 = require("../../Theme/tokens/builders/scrollbar");
|
|
9
10
|
const rowStates_1 = require("../../Theme/tokens/builders/rowStates");
|
|
10
11
|
const useExclusiveOverlay_1 = require("../../Hooks/useExclusiveOverlay");
|
|
@@ -259,7 +260,7 @@ const Dropdown = (0, react_1.forwardRef)(({ dropDownButtonStyle, ButtonText, opt
|
|
|
259
260
|
color: theme.colors.accentText,
|
|
260
261
|
boxShadow: `inset 0 0 0 2px ${theme.colors.focusRing.ring}`,
|
|
261
262
|
}, borderBottom: divider
|
|
262
|
-
? `${borderWidths_1.BORDER_WIDTHS.hairline} solid ${theme.colors
|
|
263
|
+
? `${borderWidths_1.BORDER_WIDTHS.hairline} solid ${(0, surfaceRaised_1.raisedRule)(theme.colors)}`
|
|
263
264
|
: undefined, sx: { "&:last-child": { borderBottom: "none" }, ...(0, motion_2.reducedMotionSx)() }, style: ItemStyle, fontWeight: 500, children: [option.image && ((0, jsx_runtime_1.jsx)(react_2.Box, { as: option.image, boxSize: s.img, flexShrink: 0, color: theme.colors.textMuted, style: ImageStyle })), (0, jsx_runtime_1.jsx)(react_2.Box, { as: "span", fontSize: rowSpec.fontSize, isTruncated: true, style: LabelStyle, children: option.label })] }, option.id))) }));
|
|
264
265
|
};
|
|
265
266
|
return ((0, jsx_runtime_1.jsxs)(react_2.Box, { ref: dropdownRef, position: "relative", display: "inline-block", children: [dropDownToggleOption(), isOpen && ((0, jsx_runtime_1.jsx)(react_2.Portal, { children: (0, jsx_runtime_1.jsx)(MotionBox, { ref: setMenuRef, position: "fixed", zIndex: "popover", initial: prefersReducedMotion ? false : { opacity: 0, y: -6 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: -6 }, style: {
|
|
@@ -54,12 +54,19 @@ const focusRing_styles_1 = require("../../Theme/chakra/focusRing.styles");
|
|
|
54
54
|
const borderWidths_1 = require("../../Theme/tokens/primitives/borderWidths");
|
|
55
55
|
const FileThumbnail = ({ file, radius, onPreview, }) => {
|
|
56
56
|
const url = (0, useObjectUrl_1.useObjectUrl)(file);
|
|
57
|
-
|
|
57
|
+
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
58
|
+
const preview = () => url && onPreview(url);
|
|
59
|
+
return ((0, jsx_runtime_1.jsxs)(react_2.Box, { role: "button", tabIndex: 0, "aria-label": `Preview ${file.name}`, boxSize: "2.5rem", cursor: "pointer", position: "relative", _focusVisible: (0, focusRing_styles_1.focusVisibleRing)(colors), _hover: {
|
|
58
60
|
".hover-icon": {
|
|
59
61
|
opacity: 1,
|
|
60
62
|
bg: "blackAlpha.500",
|
|
61
63
|
},
|
|
62
|
-
}, onClick:
|
|
64
|
+
}, onClick: preview, onKeyDown: (event) => {
|
|
65
|
+
if (event.key !== "Enter" && event.key !== " ")
|
|
66
|
+
return;
|
|
67
|
+
event.preventDefault();
|
|
68
|
+
preview();
|
|
69
|
+
}, children: [(0, jsx_runtime_1.jsx)("img", { src: url, alt: file.name, style: {
|
|
63
70
|
width: "100%",
|
|
64
71
|
height: "100%",
|
|
65
72
|
objectFit: "cover",
|