@hjmds/react 1.41.1 → 1.42.0
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/README.md +2 -2
- package/dist/actions.d.ts +41 -0
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +40 -3
- package/dist/actions.js.map +1 -1
- package/dist/activity-chip.d.ts.map +1 -1
- package/dist/activity-chip.js +1 -0
- package/dist/activity-chip.js.map +1 -1
- package/dist/advanced-display.d.ts +47 -14
- package/dist/advanced-display.d.ts.map +1 -1
- package/dist/advanced-display.js +72 -17
- package/dist/advanced-display.js.map +1 -1
- package/dist/advanced-forms.d.ts.map +1 -1
- package/dist/advanced-forms.js +1 -0
- package/dist/advanced-forms.js.map +1 -1
- package/dist/affix.d.ts +6 -1
- package/dist/affix.d.ts.map +1 -1
- package/dist/affix.js +5 -3
- package/dist/affix.js.map +1 -1
- package/dist/agreement.d.ts.map +1 -1
- package/dist/agreement.js +1 -0
- package/dist/agreement.js.map +1 -1
- package/dist/alert-dialog-queue.d.ts +24 -0
- package/dist/alert-dialog-queue.d.ts.map +1 -0
- package/dist/alert-dialog-queue.js +44 -0
- package/dist/alert-dialog-queue.js.map +1 -0
- package/dist/anchor.d.ts.map +1 -1
- package/dist/anchor.js +1 -0
- package/dist/anchor.js.map +1 -1
- package/dist/asset.d.ts.map +1 -1
- package/dist/asset.js +1 -0
- package/dist/asset.js.map +1 -1
- package/dist/auth-screen.d.ts.map +1 -1
- package/dist/auth-screen.js +1 -0
- package/dist/auth-screen.js.map +1 -1
- package/dist/avatar-blobatar-motion.d.ts.map +1 -1
- package/dist/avatar-blobatar-motion.js +1 -0
- package/dist/avatar-blobatar-motion.js.map +1 -1
- package/dist/avatar-blobatar.d.ts.map +1 -1
- package/dist/avatar-blobatar.js +1 -0
- package/dist/avatar-blobatar.js.map +1 -1
- package/dist/bottom-cta.d.ts.map +1 -1
- package/dist/bottom-cta.js +1 -0
- package/dist/bottom-cta.js.map +1 -1
- package/dist/bottom-info.d.ts.map +1 -1
- package/dist/bottom-info.js +1 -0
- package/dist/bottom-info.js.map +1 -1
- package/dist/bottom-navigation.d.ts.map +1 -1
- package/dist/bottom-navigation.js +1 -0
- package/dist/bottom-navigation.js.map +1 -1
- package/dist/breadcrumb.d.ts.map +1 -1
- package/dist/breadcrumb.js +1 -0
- package/dist/breadcrumb.js.map +1 -1
- package/dist/calendar.d.ts.map +1 -1
- package/dist/calendar.js +1 -0
- package/dist/calendar.js.map +1 -1
- package/dist/carousel-motion.d.ts.map +1 -1
- package/dist/carousel-motion.js +1 -0
- package/dist/carousel-motion.js.map +1 -1
- package/dist/carousel.d.ts.map +1 -1
- package/dist/carousel.js +1 -0
- package/dist/carousel.js.map +1 -1
- package/dist/celebration.d.ts.map +1 -1
- package/dist/celebration.js +1 -0
- package/dist/celebration.js.map +1 -1
- package/dist/chart.d.ts +7 -2
- package/dist/chart.d.ts.map +1 -1
- package/dist/chart.js +6 -3
- package/dist/chart.js.map +1 -1
- package/dist/choice-row.d.ts +24 -7
- package/dist/choice-row.d.ts.map +1 -1
- package/dist/choice-row.js +11 -6
- package/dist/choice-row.js.map +1 -1
- package/dist/clipboard.d.ts.map +1 -1
- package/dist/clipboard.js +1 -0
- package/dist/clipboard.js.map +1 -1
- package/dist/collapsible.d.ts.map +1 -1
- package/dist/collapsible.js +1 -0
- package/dist/collapsible.js.map +1 -1
- package/dist/collection-rail.d.ts.map +1 -1
- package/dist/collection-rail.js +3 -1
- package/dist/collection-rail.js.map +1 -1
- package/dist/color-picker.d.ts.map +1 -1
- package/dist/color-picker.js +1 -0
- package/dist/color-picker.js.map +1 -1
- package/dist/command-palette.d.ts.map +1 -1
- package/dist/command-palette.js +1 -0
- package/dist/command-palette.js.map +1 -1
- package/dist/content-transition.d.ts.map +1 -1
- package/dist/content-transition.js +1 -0
- package/dist/content-transition.js.map +1 -1
- package/dist/context-menu.d.ts.map +1 -1
- package/dist/context-menu.js +1 -0
- package/dist/context-menu.js.map +1 -1
- package/dist/conversation-row.d.ts.map +1 -1
- package/dist/conversation-row.js +1 -0
- package/dist/conversation-row.js.map +1 -1
- package/dist/data-table.d.ts.map +1 -1
- package/dist/data-table.js +1 -0
- package/dist/data-table.js.map +1 -1
- package/dist/date-entry.d.ts.map +1 -1
- package/dist/date-entry.js +1 -0
- package/dist/date-entry.js.map +1 -1
- package/dist/date-picker.d.ts.map +1 -1
- package/dist/date-picker.js +1 -0
- package/dist/date-picker.js.map +1 -1
- package/dist/date-range.d.ts.map +1 -1
- package/dist/date-range.js +1 -0
- package/dist/date-range.js.map +1 -1
- package/dist/design-profile.d.ts.map +1 -1
- package/dist/design-profile.js +1 -0
- package/dist/design-profile.js.map +1 -1
- package/dist/display.d.ts +21 -1
- package/dist/display.d.ts.map +1 -1
- package/dist/display.js +34 -8
- package/dist/display.js.map +1 -1
- package/dist/duration-field.d.ts.map +1 -1
- package/dist/duration-field.js +1 -0
- package/dist/duration-field.js.map +1 -1
- package/dist/effect-surface.d.ts.map +1 -1
- package/dist/effect-surface.js +1 -0
- package/dist/effect-surface.js.map +1 -1
- package/dist/evidence.d.ts +1 -1
- package/dist/evidence.js +1 -1
- package/dist/evidence.js.map +1 -1
- package/dist/feedback.d.ts.map +1 -1
- package/dist/feedback.js +1 -0
- package/dist/feedback.js.map +1 -1
- package/dist/field-group.d.ts.map +1 -1
- package/dist/field-group.js +1 -0
- package/dist/field-group.js.map +1 -1
- package/dist/file-picker.d.ts.map +1 -1
- package/dist/file-picker.js +1 -0
- package/dist/file-picker.js.map +1 -1
- package/dist/floating-action-button.d.ts.map +1 -1
- package/dist/floating-action-button.js +1 -0
- package/dist/floating-action-button.js.map +1 -1
- package/dist/folder-preview.d.ts.map +1 -1
- package/dist/folder-preview.js +1 -0
- package/dist/folder-preview.js.map +1 -1
- package/dist/forms.d.ts +30 -6
- package/dist/forms.d.ts.map +1 -1
- package/dist/forms.js +56 -14
- package/dist/forms.js.map +1 -1
- package/dist/gravity-letters.d.ts.map +1 -1
- package/dist/gravity-letters.js +1 -0
- package/dist/gravity-letters.js.map +1 -1
- package/dist/grid-reveal.d.ts.map +1 -1
- package/dist/grid-reveal.js +1 -0
- package/dist/grid-reveal.js.map +1 -1
- package/dist/heading.d.ts.map +1 -1
- package/dist/heading.js +1 -0
- package/dist/heading.js.map +1 -1
- package/dist/image-choice.d.ts.map +1 -1
- package/dist/image-choice.js +1 -0
- package/dist/image-choice.js.map +1 -1
- package/dist/image-comparison.d.ts.map +1 -1
- package/dist/image-comparison.js +1 -0
- package/dist/image-comparison.js.map +1 -1
- package/dist/image-viewer.d.ts +22 -1
- package/dist/image-viewer.d.ts.map +1 -1
- package/dist/image-viewer.js +14 -1
- package/dist/image-viewer.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/inline-confirm.d.ts.map +1 -1
- package/dist/inline-confirm.js +1 -0
- package/dist/inline-confirm.js.map +1 -1
- package/dist/internal/document-resource.d.ts.map +1 -1
- package/dist/internal/document-resource.js +1 -0
- package/dist/internal/document-resource.js.map +1 -1
- package/dist/internal/initial-focus.d.ts.map +1 -1
- package/dist/internal/initial-focus.js +1 -0
- package/dist/internal/initial-focus.js.map +1 -1
- package/dist/internal/media-album.d.ts.map +1 -1
- package/dist/internal/media-album.js +1 -0
- package/dist/internal/media-album.js.map +1 -1
- package/dist/internal/message-reactions.d.ts.map +1 -1
- package/dist/internal/message-reactions.js +1 -0
- package/dist/internal/message-reactions.js.map +1 -1
- package/dist/internal/overlay-origin-motion.d.ts.map +1 -1
- package/dist/internal/overlay-origin-motion.js +1 -0
- package/dist/internal/overlay-origin-motion.js.map +1 -1
- package/dist/internal/pending-content.d.ts.map +1 -1
- package/dist/internal/pending-content.js +1 -0
- package/dist/internal/pending-content.js.map +1 -1
- package/dist/internal/photo-source-icon.d.ts.map +1 -1
- package/dist/internal/photo-source-icon.js +1 -0
- package/dist/internal/photo-source-icon.js.map +1 -1
- package/dist/internal/screen-exit.d.ts.map +1 -1
- package/dist/internal/screen-exit.js +1 -0
- package/dist/internal/screen-exit.js.map +1 -1
- package/dist/internal/screen-footer.d.ts.map +1 -1
- package/dist/internal/screen-footer.js +1 -0
- package/dist/internal/screen-footer.js.map +1 -1
- package/dist/internal/spinner.d.ts.map +1 -1
- package/dist/internal/spinner.js +1 -0
- package/dist/internal/spinner.js.map +1 -1
- package/dist/internal/use-composition-action.d.ts.map +1 -1
- package/dist/internal/use-composition-action.js +1 -0
- package/dist/internal/use-composition-action.js.map +1 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -0
- package/dist/internal.js.map +1 -1
- package/dist/layout.d.ts +11 -1
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +8 -4
- package/dist/layout.js.map +1 -1
- package/dist/mentions.d.ts.map +1 -1
- package/dist/mentions.js +1 -0
- package/dist/mentions.js.map +1 -1
- package/dist/menu-morph.d.ts.map +1 -1
- package/dist/menu-morph.js +1 -0
- package/dist/menu-morph.js.map +1 -1
- package/dist/menubar.d.ts.map +1 -1
- package/dist/menubar.js +1 -0
- package/dist/menubar.js.map +1 -1
- package/dist/modal.d.ts.map +1 -1
- package/dist/modal.js +1 -0
- package/dist/modal.js.map +1 -1
- package/dist/navigation-bar.d.ts.map +1 -1
- package/dist/navigation-bar.js +1 -0
- package/dist/navigation-bar.js.map +1 -1
- package/dist/navigation.d.ts.map +1 -1
- package/dist/navigation.js +1 -0
- package/dist/navigation.js.map +1 -1
- package/dist/notification-bell.d.ts +1 -1
- package/dist/notification-bell.d.ts.map +1 -1
- package/dist/notification-bell.js +5 -1
- package/dist/notification-bell.js.map +1 -1
- package/dist/number-field.d.ts.map +1 -1
- package/dist/number-field.js +1 -0
- package/dist/number-field.js.map +1 -1
- package/dist/overlay-stack.d.ts.map +1 -1
- package/dist/overlay-stack.js +1 -0
- package/dist/overlay-stack.js.map +1 -1
- package/dist/overlays.d.ts.map +1 -1
- package/dist/overlays.js +11 -2
- package/dist/overlays.js.map +1 -1
- package/dist/pagination.d.ts.map +1 -1
- package/dist/pagination.js +1 -0
- package/dist/pagination.js.map +1 -1
- package/dist/popover.d.ts.map +1 -1
- package/dist/popover.js +1 -0
- package/dist/popover.js.map +1 -1
- package/dist/portal.d.ts.map +1 -1
- package/dist/portal.js +1 -0
- package/dist/portal.js.map +1 -1
- package/dist/progressive-blur.d.ts.map +1 -1
- package/dist/progressive-blur.js +1 -0
- package/dist/progressive-blur.js.map +1 -1
- package/dist/provider-button.d.ts.map +1 -1
- package/dist/provider-button.js +1 -0
- package/dist/provider-button.js.map +1 -1
- package/dist/provider.d.ts +9 -1
- package/dist/provider.d.ts.map +1 -1
- package/dist/provider.js +2 -2
- package/dist/provider.js.map +1 -1
- package/dist/public-exports.generated.d.ts +3 -0
- package/dist/public-exports.generated.d.ts.map +1 -1
- package/dist/public-exports.generated.js +9 -0
- package/dist/public-exports.generated.js.map +1 -1
- package/dist/rating.d.ts.map +1 -1
- package/dist/rating.js +1 -0
- package/dist/rating.js.map +1 -1
- package/dist/reaction-picker.d.ts.map +1 -1
- package/dist/reaction-picker.js +1 -0
- package/dist/reaction-picker.js.map +1 -1
- package/dist/saved-items.d.ts.map +1 -1
- package/dist/saved-items.js +1 -0
- package/dist/saved-items.js.map +1 -1
- package/dist/screen-flows.d.ts +5 -1
- package/dist/screen-flows.d.ts.map +1 -1
- package/dist/screen-flows.js +13 -4
- package/dist/screen-flows.js.map +1 -1
- package/dist/screens.d.ts +24 -4
- package/dist/screens.d.ts.map +1 -1
- package/dist/screens.js +38 -11
- package/dist/screens.js.map +1 -1
- package/dist/scroll-progress.d.ts.map +1 -1
- package/dist/scroll-progress.js +1 -0
- package/dist/scroll-progress.js.map +1 -1
- package/dist/select.d.ts.map +1 -1
- package/dist/select.js +1 -0
- package/dist/select.js.map +1 -1
- package/dist/selection.d.ts +7 -1
- package/dist/selection.d.ts.map +1 -1
- package/dist/selection.js +33 -10
- package/dist/selection.js.map +1 -1
- package/dist/side-panel.d.ts.map +1 -1
- package/dist/side-panel.js +1 -0
- package/dist/side-panel.js.map +1 -1
- package/dist/sidebar.d.ts +21 -2
- package/dist/sidebar.d.ts.map +1 -1
- package/dist/sidebar.js +40 -20
- package/dist/sidebar.js.map +1 -1
- package/dist/skip-nav.d.ts.map +1 -1
- package/dist/skip-nav.js +1 -0
- package/dist/skip-nav.js.map +1 -1
- package/dist/slider.d.ts.map +1 -1
- package/dist/slider.js +1 -0
- package/dist/slider.js.map +1 -1
- package/dist/sortable.d.ts.map +1 -1
- package/dist/sortable.js +1 -0
- package/dist/sortable.js.map +1 -1
- package/dist/splitter.d.ts.map +1 -1
- package/dist/splitter.js +1 -0
- package/dist/splitter.js.map +1 -1
- package/dist/statistic-motion.d.ts.map +1 -1
- package/dist/statistic-motion.js +1 -0
- package/dist/statistic-motion.js.map +1 -1
- package/dist/status-text.d.ts.map +1 -1
- package/dist/status-text.js +1 -0
- package/dist/status-text.js.map +1 -1
- package/dist/step-player.d.ts.map +1 -1
- package/dist/step-player.js +1 -0
- package/dist/step-player.js.map +1 -1
- package/dist/steps.d.ts +16 -14
- package/dist/steps.d.ts.map +1 -1
- package/dist/steps.js +26 -9
- package/dist/steps.js.map +1 -1
- package/dist/styles.css +140 -35
- package/dist/styles.layered.css +140 -35
- package/dist/supplemental-display.d.ts.map +1 -1
- package/dist/supplemental-display.js +1 -0
- package/dist/supplemental-display.js.map +1 -1
- package/dist/supplemental-navigation.d.ts.map +1 -1
- package/dist/supplemental-navigation.js +1 -0
- package/dist/supplemental-navigation.js.map +1 -1
- package/dist/swipe-actions.d.ts.map +1 -1
- package/dist/swipe-actions.js +1 -0
- package/dist/swipe-actions.js.map +1 -1
- package/dist/table-family.d.ts.map +1 -1
- package/dist/table-family.js +1 -0
- package/dist/table-family.js.map +1 -1
- package/dist/table-sort-button.d.ts.map +1 -1
- package/dist/table-sort-button.js +1 -0
- package/dist/table-sort-button.js.map +1 -1
- package/dist/tags-input.d.ts.map +1 -1
- package/dist/tags-input.js +1 -0
- package/dist/tags-input.js.map +1 -1
- package/dist/task-list.d.ts.map +1 -1
- package/dist/task-list.js +1 -0
- package/dist/task-list.js.map +1 -1
- package/dist/text-annotation.d.ts.map +1 -1
- package/dist/text-annotation.js +1 -0
- package/dist/text-annotation.js.map +1 -1
- package/dist/text-formats.d.ts.map +1 -1
- package/dist/text-formats.js +1 -0
- package/dist/text-formats.js.map +1 -1
- package/dist/theme.d.ts.map +1 -1
- package/dist/theme.js +12 -1
- package/dist/theme.js.map +1 -1
- package/dist/thinking-orb.d.ts.map +1 -1
- package/dist/thinking-orb.js +1 -0
- package/dist/thinking-orb.js.map +1 -1
- package/dist/toast.d.ts.map +1 -1
- package/dist/toast.js +1 -0
- package/dist/toast.js.map +1 -1
- package/dist/toggle-group.d.ts.map +1 -1
- package/dist/toggle-group.js +1 -0
- package/dist/toggle-group.js.map +1 -1
- package/dist/top-bar.d.ts.map +1 -1
- package/dist/top-bar.js +1 -0
- package/dist/top-bar.js.map +1 -1
- package/dist/top.d.ts.map +1 -1
- package/dist/top.js +4 -3
- package/dist/top.js.map +1 -1
- package/dist/tour.d.ts.map +1 -1
- package/dist/tour.js +1 -0
- package/dist/tour.js.map +1 -1
- package/dist/transfer-list.d.ts.map +1 -1
- package/dist/transfer-list.js +1 -0
- package/dist/transfer-list.js.map +1 -1
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +1 -0
- package/dist/tree.js.map +1 -1
- package/dist/upload-item.d.ts.map +1 -1
- package/dist/upload-item.js +1 -0
- package/dist/upload-item.js.map +1 -1
- package/dist/virtual-list.d.ts.map +1 -1
- package/dist/virtual-list.js +1 -0
- package/dist/virtual-list.js.map +1 -1
- package/dist/voice-note.d.ts.map +1 -1
- package/dist/voice-note.js +1 -0
- package/dist/voice-note.js.map +1 -1
- package/package.json +8 -3
package/dist/layout.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { type ContainerGutter, type ContainerSize } from "@hjmds/design-contract
|
|
|
4
4
|
import { type LayoutSidebarRole } from "@hjmds/design-contracts/components/layout";
|
|
5
5
|
import { type SurfacePadding, type SurfaceRadius, type SurfaceTone } from "@hjmds/design-contracts/recipes/base";
|
|
6
6
|
import { type StackAlign, type StackAxis, type StackGap, type StackJustify, type TextEmphasis, type TextTone } from "@hjmds/design-contracts/recipes";
|
|
7
|
-
import { type FontRole, type NumericVariant, type TextVariant } from "@hjmds/design-contracts/foundations";
|
|
7
|
+
import { type ElevationStep, type FontRole, type NumericVariant, type TextVariant } from "@hjmds/design-contracts/foundations";
|
|
8
8
|
import { type AnchorHTMLAttributes, type HTMLAttributes, type ReactElement, type ReactNode, type Ref } from "react";
|
|
9
9
|
import type { HjmCompositionStyleProp } from "./composition-style.js";
|
|
10
10
|
export type { SurfacePadding, SurfaceRadius, SurfaceTone, } from "@hjmds/design-contracts/recipes/base";
|
|
@@ -109,6 +109,11 @@ export type SurfaceProps = HTMLAttributes<HTMLElement> & Readonly<{
|
|
|
109
109
|
bordered?: boolean;
|
|
110
110
|
padding?: SurfacePadding;
|
|
111
111
|
radius?: SurfaceRadius;
|
|
112
|
+
/**
|
|
113
|
+
* Shadow token step (`--hjm-shadow-*`). Omitted, the tone decides (raised → raised, others none); `none` removes
|
|
114
|
+
* the raised shadow. An elevated surface does not clip its content, as the raised tone.
|
|
115
|
+
*/
|
|
116
|
+
elevation?: ElevationStep;
|
|
112
117
|
/** Canonical layout-only placement. Controlled visual keys are excluded. */
|
|
113
118
|
layoutStyle?: HjmCompositionStyleProp;
|
|
114
119
|
}>;
|
|
@@ -121,6 +126,11 @@ export declare const Surface: import("react").ForwardRefExoticComponent<HTMLAttr
|
|
|
121
126
|
bordered?: boolean;
|
|
122
127
|
padding?: SurfacePadding;
|
|
123
128
|
radius?: SurfaceRadius;
|
|
129
|
+
/**
|
|
130
|
+
* Shadow token step (`--hjm-shadow-*`). Omitted, the tone decides (raised → raised, others none); `none` removes
|
|
131
|
+
* the raised shadow. An elevated surface does not clip its content, as the raised tone.
|
|
132
|
+
*/
|
|
133
|
+
elevation?: ElevationStep;
|
|
124
134
|
/** Canonical layout-only placement. Controlled visual keys are excluded. */
|
|
125
135
|
layoutStyle?: HjmCompositionStyleProp;
|
|
126
136
|
}> & import("react").RefAttributes<HTMLElement>>;
|
package/dist/layout.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.tsx"],"names":[],"mappings":"AAKA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,OAAO,EACb,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,aAAa,EACnB,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,WAAW,EACjB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,QAAQ,EACd,MAAM,iCAAiC,CAAC;AACzC,OAAO,
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.tsx"],"names":[],"mappings":"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"}
|
package/dist/layout.js
CHANGED
|
@@ -9,7 +9,7 @@ import { resolveContainerDescriptor, } from "@hjmds/design-contracts/components/
|
|
|
9
9
|
import { layoutRecipe, validateLayoutWebDescriptor, } from "@hjmds/design-contracts/components/layout";
|
|
10
10
|
import { surfaceDefaults, surfaceGeometry, surfaceRecipe, } from "@hjmds/design-contracts/recipes/base";
|
|
11
11
|
import { resolveTextDefaultWeight, stackRecipe, textRecipe, } from "@hjmds/design-contracts/recipes";
|
|
12
|
-
import { numeric as numericVariants, resolveTextFontRole, typography } from "@hjmds/design-contracts/foundations";
|
|
12
|
+
import { numeric as numericVariants, resolveTextFontRole, typography, validateElevationStep } from "@hjmds/design-contracts/foundations";
|
|
13
13
|
import { createElement, forwardRef, useId, useRef, } from "react";
|
|
14
14
|
import { classNames, composeRefs, useElementWidth, useWindowWidth, } from "./internal.js";
|
|
15
15
|
function hasRegionContent(content) {
|
|
@@ -120,8 +120,11 @@ export const Text = forwardRef(function Text({ as = "span", variant = textRecipe
|
|
|
120
120
|
},
|
|
121
121
|
});
|
|
122
122
|
});
|
|
123
|
-
export const Surface = forwardRef(function Surface({ as = "div", tone = surfaceDefaults.tone, bordered, padding = surfaceDefaults.padding, radius = surfaceDefaults.radius, className, layoutStyle, style, ...props }, ref) {
|
|
123
|
+
export const Surface = forwardRef(function Surface({ as = "div", tone = surfaceDefaults.tone, bordered, padding = surfaceDefaults.padding, radius = surfaceDefaults.radius, elevation, className, layoutStyle, style, ...props }, ref) {
|
|
124
124
|
const contract = surfaceRecipe[tone];
|
|
125
|
+
if (elevation !== undefined)
|
|
126
|
+
validateElevationStep(elevation, "Surface");
|
|
127
|
+
const lifted = elevation === undefined ? contract.elevated : elevation !== "none";
|
|
125
128
|
return createElement(as, {
|
|
126
129
|
...props,
|
|
127
130
|
ref,
|
|
@@ -129,8 +132,9 @@ export const Surface = forwardRef(function Surface({ as = "div", tone = surfaceD
|
|
|
129
132
|
"data-tone": tone,
|
|
130
133
|
// Canvas framing is the default; preserve the caller's explicit border opt-out.
|
|
131
134
|
"data-bordered": bordered ?? (surfaceDefaults.bordered || contract.borderAlways),
|
|
132
|
-
"data-elevated":
|
|
133
|
-
"data-
|
|
135
|
+
"data-elevated": lifted,
|
|
136
|
+
"data-elevation": elevation,
|
|
137
|
+
"data-clips": contract.clipsContent && !lifted,
|
|
134
138
|
"data-padding": padding,
|
|
135
139
|
"data-radius": radius,
|
|
136
140
|
style: {
|
package/dist/layout.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../src/layout.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\n// Layout renderers read profile context; declaring this granular entry keeps server-owned guide text outside the client graph.\n// Root-barrel marking would also move unrelated exports; see docs/qa/2026-10-07-rsc-profile-boundary.md.\nimport { useDesignProfileDefaults } from \"./internal.js\";\nimport {\n resolveGridLayout,\n type GridDescriptor,\n type GridGap,\n} from \"@hjmds/design-contracts/grid\";\nimport {\n resolveAspectRatioDescriptor,\n type AspectRatioValue,\n} from \"@hjmds/design-contracts/components/aspect-ratio\";\nimport {\n resolveContainerDescriptor,\n type ContainerGutter,\n type ContainerSize,\n} from \"@hjmds/design-contracts/components/container\";\nimport {\n layoutRecipe,\n validateLayoutWebDescriptor,\n type LayoutSidebarDescriptor,\n type LayoutSidebarRole,\n} from \"@hjmds/design-contracts/components/layout\";\nimport {\n surfaceDefaults,\n surfaceGeometry,\n surfaceRecipe,\n type SurfacePadding,\n type SurfaceRadius,\n type SurfaceTone,\n} from \"@hjmds/design-contracts/recipes/base\";\nimport {\n resolveTextDefaultWeight,\n stackRecipe,\n textRecipe,\n type StackAlign,\n type StackAxis,\n type StackGap,\n type StackJustify,\n type TextEmphasis,\n type TextTone,\n} from \"@hjmds/design-contracts/recipes\";\nimport { numeric as numericVariants, resolveTextFontRole, typography, type FontRole, type NumericVariant, type TextVariant } from \"@hjmds/design-contracts/foundations\";\nimport {\n createElement,\n forwardRef,\n useId,\n useRef,\n type AnchorHTMLAttributes,\n type HTMLAttributes,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport {\n classNames,\n composeRefs,\n useElementWidth,\n useWindowWidth,\n} from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type {\n SurfacePadding,\n SurfaceRadius,\n SurfaceTone,\n} from \"@hjmds/design-contracts/recipes/base\";\nexport type {\n StackAlign,\n StackAxis,\n StackGap,\n StackJustify,\n TextEmphasis,\n TextTone,\n} from \"@hjmds/design-contracts/recipes\";\n\ntype LayoutRegionProps = Omit<\n HTMLAttributes<HTMLElement>,\n \"children\" | \"role\"\n>;\n\ntype LayoutSidebarBase = Readonly<{\n children: ReactNode;\n role: LayoutSidebarRole;\n label: string;\n landmarkProps?: Omit<LayoutRegionProps, \"aria-label\">;\n landmarkRef?: Ref<HTMLElement>;\n}>;\n\n/**\n * A persistent sidebar is rendered in the shell grid. An overlay sidebar is\n * deliberately handed to the product's SidePanel (or equivalent) through\n * `renderOverlay`; Layout never owns a second open/dismiss lifecycle.\n */\nexport type LayoutSidebar =\n | (LayoutSidebarBase &\n Readonly<{\n mode: \"persistent\";\n renderOverlay?: never;\n }>)\n | (LayoutSidebarBase &\n Readonly<{\n mode: \"overlay\";\n renderOverlay(sidebarLandmark: ReactElement): ReactNode;\n }>);\n\nexport type LayoutProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> &\n Readonly<{\n children: ReactNode;\n header?: ReactNode;\n footer?: ReactNode;\n sidebar?: LayoutSidebar;\n skipLinkLabel?: string;\n /** Stable product id for deep links; a hydration-safe id is generated when omitted. */\n mainId?: string;\n mainRef?: Ref<HTMLElement>;\n headerProps?: LayoutRegionProps;\n mainProps?: Omit<LayoutRegionProps, \"id\" | \"tabIndex\">;\n footerProps?: LayoutRegionProps;\n skipLinkProps?: Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n \"children\" | \"href\"\n >;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nfunction hasRegionContent(content: ReactNode | undefined): boolean {\n return content !== undefined && content !== null && content !== false;\n}\n\nfunction assertMainId(id: string): void {\n if (id.trim().length === 0) {\n throw new TypeError(\"Layout mainId must not be empty\");\n }\n if (/\\s/u.test(id)) {\n throw new TypeError(\"Layout mainId must not contain whitespace\");\n }\n}\n\n/** Accessible Web app shell with real landmarks and bypass navigation. */\nexport const Layout = forwardRef<HTMLDivElement, LayoutProps>(function Layout(\n {\n children,\n header,\n footer,\n sidebar,\n skipLinkLabel,\n mainId: mainIdProp,\n mainRef: forwardedMainRef,\n headerProps,\n mainProps,\n footerProps,\n skipLinkProps,\n className,\n layoutStyle,\n ...props\n },\n ref,\n) {\n const generatedId = `hjm-main-${useId().replaceAll(\":\", \"\")}`;\n const internalMainRef = useRef<HTMLElement>(null);\n const mainId = mainIdProp ?? generatedId;\n assertMainId(mainId);\n\n const hasHeader = hasRegionContent(header);\n const hasFooter = hasRegionContent(footer);\n const descriptor = {\n ...(hasHeader ? { hasHeader: true } : {}),\n ...(hasFooter ? { hasFooter: true } : {}),\n ...(sidebar === undefined\n ? {}\n : {\n sidebar: {\n role: sidebar.role,\n mode: sidebar.mode,\n label: sidebar.label,\n } satisfies LayoutSidebarDescriptor,\n }),\n ...(skipLinkLabel === undefined ? {} : { skipLinkLabel }),\n };\n validateLayoutWebDescriptor(descriptor);\n\n if (\n sidebar?.mode === \"overlay\" &&\n typeof sidebar.renderOverlay !== \"function\"\n ) {\n throw new TypeError(\n \"Layout overlay sidebar requires renderOverlay so SidePanel owns its lifecycle\",\n );\n }\n\n const {\n className: headerClassName,\n ...restHeaderProps\n } = headerProps ?? {};\n const {\n className: mainClassName,\n style: mainStyle,\n ...restMainProps\n } = mainProps ?? {};\n const {\n className: footerClassName,\n ...restFooterProps\n } = footerProps ?? {};\n const {\n className: skipLinkClassName,\n onClick: onSkipLinkClick,\n ...restSkipLinkProps\n } = skipLinkProps ?? {};\n\n let sidebarNode: ReactNode;\n if (sidebar !== undefined) {\n const {\n className: sidebarClassName,\n style: sidebarStyle,\n ...restSidebarProps\n } = sidebar.landmarkProps ?? {};\n const sidebarLandmark = createElement(\n sidebar.role === \"navigation\" ? \"nav\" : \"aside\",\n {\n ...restSidebarProps,\n ref: sidebar.landmarkRef,\n className: classNames(\"hjm-layout__sidebar\", sidebarClassName),\n \"aria-label\": sidebar.label,\n \"data-mode\": sidebar.mode,\n style: {\n ...(sidebar.mode === \"persistent\"\n ? { inlineSize: layoutRecipe.sidebar.width }\n : {}),\n ...sidebarStyle,\n },\n },\n sidebar.children,\n );\n sidebarNode = sidebar.mode === \"overlay\"\n ? sidebar.renderOverlay(sidebarLandmark)\n : sidebarLandmark;\n }\n\n const moveFocusToMain = (event: MouseEvent<HTMLAnchorElement>) => {\n onSkipLinkClick?.(event);\n if (event.defaultPrevented) return;\n const main = internalMainRef.current;\n if (main === null) return;\n event.preventDefault();\n const url = new URL(window.location.href);\n url.hash = mainId;\n window.history.replaceState(window.history.state, \"\", url);\n main.focus({ preventScroll: true });\n main.scrollIntoView?.({ block: \"start\" });\n };\n\n return (\n <div\n {...props}\n style={{ ...props.style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-layout\", className)}\n data-hjm-component=\"Layout\"\n data-sidebar-mode={sidebar?.mode ?? \"none\"}\n >\n {skipLinkLabel === undefined ? null : (\n <a\n {...restSkipLinkProps}\n href={`#${mainId}`}\n className={classNames(\n \"hjm-layout__skip-link\",\n skipLinkClassName,\n )}\n onClick={moveFocusToMain}\n >\n {skipLinkLabel}\n </a>\n )}\n {hasHeader ? (\n <header\n {...restHeaderProps}\n className={classNames(\"hjm-layout__header\", headerClassName)}\n >\n {header}\n </header>\n ) : null}\n {sidebarNode}\n <main\n {...restMainProps}\n ref={composeRefs(internalMainRef, forwardedMainRef)}\n id={mainId}\n className={classNames(\"hjm-layout__main\", mainClassName)}\n tabIndex={-1}\n style={{\n maxInlineSize: layoutRecipe.main.maxWidth,\n paddingInline: layoutRecipe.main.paddingHorizontal,\n ...mainStyle,\n }}\n >\n {children}\n </main>\n {hasFooter ? (\n <footer\n {...restFooterProps}\n className={classNames(\"hjm-layout__footer\", footerClassName)}\n >\n {footer}\n </footer>\n ) : null}\n </div>\n );\n});\n\nexport type TextProps = Omit<HTMLAttributes<HTMLElement>, \"children\" | \"color\"> &\n Readonly<{\n children: ReactNode;\n as?: \"span\" | \"p\" | \"div\" | \"strong\" | \"small\";\n variant?: TextVariant;\n /** Overrides the variant family role; never changes its semantic element or metrics. */\n fontRole?: FontRole;\n tone?: TextTone;\n /**\n * Product-owned color role (team, sentiment, chart series) replacing the `tone` color while the HJM variant\n * metrics and font face stay. Mirrors Native, where dropping to a raw text host lost the face (2026-10-18).\n * Replaces the legacy HTML `color` attribute type, which no browser applies to text. Contrast is the product's.\n */\n color?: string;\n /** Digit spacing; `tabular` keeps changing numbers (scores, timers, counts) from shifting the layout. */\n numeric?: NumericVariant;\n emphasis?: TextEmphasis;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Text = forwardRef<HTMLElement, TextProps>(function Text(\n {\n as = \"span\",\n variant = textRecipe.defaults.variant,\n fontRole,\n tone = textRecipe.defaults.tone,\n color,\n numeric,\n emphasis: suppliedEmphasis,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n const profile = useDesignProfileDefaults();\n const emphasis = suppliedEmphasis ?? textRecipe.defaults.emphasis;\n const defaultWeight = suppliedEmphasis === undefined\n ? resolveTextDefaultWeight(variant, profile?.tokens.typography ?? typography, profile !== undefined)\n : undefined;\n return createElement(as, {\n ...props,\n ref,\n className: classNames(\"hjm-text\", className),\n \"data-variant\": variant,\n \"data-font-role\": resolveTextFontRole(variant, fontRole ?? (props.role === \"heading\" ? \"display\" : undefined)),\n \"data-tone\": tone,\n \"data-emphasis\": emphasis,\n // The variant default weight goes first so caller `style`/placement win, matching Native's style order\n // (it used to be spread last and overrode an explicit style weight under a profile).\n \"data-numeric\": numeric,\n style: {\n ...(defaultWeight === undefined ? {} : { fontWeight: defaultWeight }),\n ...(color === undefined ? {} : { color }),\n ...(numeric === undefined ? {} : { fontVariantNumeric: numericVariants[numeric] }),\n ...style,\n ...layoutStyle,\n },\n });\n});\n\nexport type SurfaceProps = HTMLAttributes<HTMLElement> &\n Readonly<{\n as?: \"div\" | \"section\" | \"article\" | \"button\";\n /** Native button host used by interactive Card; passive surfaces remain divs. */\n type?: \"button\";\n disabled?: boolean;\n tone?: SurfaceTone;\n bordered?: boolean;\n padding?: SurfacePadding;\n radius?: SurfaceRadius;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Surface = forwardRef<HTMLElement, SurfaceProps>(function Surface(\n {\n as = \"div\",\n tone = surfaceDefaults.tone,\n bordered,\n padding = surfaceDefaults.padding,\n radius = surfaceDefaults.radius,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n const contract = surfaceRecipe[tone];\n return createElement(as, {\n ...props,\n ref,\n className: classNames(\"hjm-surface\", className),\n \"data-tone\": tone,\n // Canvas framing is the default; preserve the caller's explicit border opt-out.\n \"data-bordered\": bordered ?? (surfaceDefaults.bordered || contract.borderAlways),\n \"data-elevated\": contract.elevated,\n \"data-clips\": contract.clipsContent,\n \"data-padding\": padding,\n \"data-radius\": radius,\n style: {\n padding: surfaceGeometry.paddings[padding],\n borderRadius: `var(--hjm-radius-${radius})`,\n ...style,\n ...layoutStyle,\n },\n });\n});\n\nexport type StackProps = HTMLAttributes<HTMLDivElement> &\n Readonly<{\n axis?: StackAxis;\n gap?: StackGap;\n align?: StackAlign;\n justify?: StackJustify;\n wrap?: boolean;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nconst justifyValues = {\n start: \"flex-start\",\n center: \"center\",\n end: \"flex-end\",\n between: \"space-between\",\n} as const;\n\nexport const Stack = forwardRef<HTMLDivElement, StackProps>(function Stack(\n {\n axis = stackRecipe.defaults.axis,\n gap = stackRecipe.defaults.gap,\n align = stackRecipe.defaults.align,\n justify = stackRecipe.defaults.justify,\n wrap = stackRecipe.defaults.wrap,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n return (\n <div\n {...props}\n ref={ref}\n className={classNames(\"hjm-stack\", className)}\n data-axis={axis}\n data-gap={gap}\n style={{\n display: \"flex\",\n flexDirection: stackRecipe.axes[axis],\n gap: stackRecipe.gaps[gap],\n alignItems: align === \"start\" || align === \"end\" ? `flex-${align}` : align,\n justifyContent: justifyValues[justify],\n flexWrap: wrap ? \"wrap\" : \"nowrap\",\n ...style,\n ...layoutStyle,\n }}\n />\n );\n});\n\nexport type ContainerProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> &\n Readonly<{\n children?: ReactNode;\n size?: ContainerSize;\n gutter?: ContainerGutter;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\n/** A centered, token-guttered content boundary shared with Native large screens. */\nexport const Container = forwardRef<HTMLDivElement, ContainerProps>(function Container(\n { size, gutter, className, layoutStyle, style, ...props },\n ref,\n) {\n const resolved = resolveContainerDescriptor({\n ...(size === undefined ? {} : { size }),\n ...(gutter === undefined ? {} : { gutter }),\n });\n return (\n <div\n {...props}\n ref={ref}\n className={classNames(\"hjm-container\", className)}\n data-size={resolved.size}\n data-gutter={resolved.gutter}\n style={{\n maxInlineSize: resolved.maxWidth ?? undefined,\n paddingInline: resolved.paddingInline,\n ...style,\n ...layoutStyle,\n }}\n />\n );\n});\n\nexport type AspectRatioProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> &\n Readonly<{\n children?: ReactNode;\n ratio?: AspectRatioValue;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\n/** Responsive media frame. Products retain object-fit, crop, and content semantics. */\nexport const AspectRatio = forwardRef<HTMLDivElement, AspectRatioProps>(function AspectRatio(\n { ratio, className, layoutStyle, style, ...props },\n ref,\n) {\n const resolved = resolveAspectRatioDescriptor(\n ratio === undefined ? {} : { ratio },\n );\n return (\n <div\n {...props}\n ref={ref}\n className={classNames(\"hjm-aspect-ratio\", className)}\n data-ratio={resolved.source}\n style={{ ...layoutStyle, aspectRatio: resolved.ratio, ...style }}\n />\n );\n});\n\n// No `layoutStyle`: the element is clipped to 1px by design, so placement has no visible effect.\nexport type VisuallyHiddenProps = HTMLAttributes<HTMLSpanElement> &\n Readonly<{ children: ReactNode }>;\n\n/** Keeps meaningful copy available to assistive technology without visible layout. */\nexport const VisuallyHidden = forwardRef<HTMLSpanElement, VisuallyHiddenProps>(\n function VisuallyHidden({ className, ...props }, ref) {\n return (\n <span\n {...props}\n ref={ref}\n className={classNames(\"hjm-visually-hidden\", className)}\n />\n );\n },\n);\n\nexport type GridProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> &\n Pick<GridDescriptor, \"columns\" | \"gap\" | \"minColumnWidth\"> &\n Readonly<{\n children?: ReactNode;\n /** Test/SSR override. Browser renderers otherwise observe window.innerWidth. */\n windowWidth?: number;\n /** Container measurement override; ResizeObserver is used when omitted. */\n availableWidth?: number;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Grid = forwardRef<HTMLDivElement, GridProps>(function Grid(\n {\n columns,\n gap,\n minColumnWidth,\n windowWidth,\n availableWidth,\n className,\n layoutStyle,\n style,\n ...props\n },\n forwardedRef,\n) {\n const browserWindowWidth = useWindowWidth();\n const [measuredWidth, gridRef] = useElementWidth(forwardedRef);\n const compactSsrWidth = 320;\n const effectiveWindowWidth =\n windowWidth ??\n (browserWindowWidth > 0 ? browserWindowWidth : compactSsrWidth);\n const effectiveAvailableWidth =\n availableWidth ??\n (measuredWidth !== undefined && measuredWidth > 0\n ? measuredWidth\n : effectiveWindowWidth);\n const descriptor: GridDescriptor = {\n columns,\n ...(gap === undefined ? {} : { gap }),\n ...(minColumnWidth === undefined ? {} : { minColumnWidth }),\n };\n const layout = resolveGridLayout(descriptor, {\n windowWidth: effectiveWindowWidth,\n availableWidth: effectiveAvailableWidth,\n });\n\n return (\n <div\n {...props}\n ref={gridRef}\n className={classNames(\"hjm-grid\", className)}\n data-window-class={layout.windowClass}\n data-columns={layout.columns}\n data-requested-columns={layout.requestedColumns}\n data-state={layout.columns < layout.requestedColumns ? \"collapsed\" : \"resolved\"}\n style={{\n display: \"grid\",\n gridTemplateColumns: `repeat(${layout.columns}, minmax(0, 1fr))`,\n rowGap: layout.rowGap,\n columnGap: layout.columnGap,\n ...style,\n ...layoutStyle,\n }}\n />\n );\n});\n\nexport type SectionProps = Omit<HTMLAttributes<HTMLElement>, \"children\" | \"title\"> &\n Readonly<{\n title?: ReactNode;\n description?: ReactNode;\n action?: ReactNode;\n children: ReactNode;\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\n/** Large-text-safe semantic content section with an optional header action. */\nexport const Section = forwardRef<HTMLElement, SectionProps>(function Section(\n {\n title,\n description,\n action,\n children,\n headingLevel = 2,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n const hasHeader = title !== undefined || description !== undefined || action !== undefined;\n return (\n <section {...props} style={{ ...style, ...layoutStyle }} ref={ref} className={classNames(\"hjm-section\", className)}>\n {hasHeader ? (\n <header className=\"hjm-section__header\">\n <div className=\"hjm-section__copy\">\n {title === undefined ? null : createElement(\n `h${headingLevel}`,\n { className: \"hjm-section__title\" },\n title,\n )}\n {description === undefined ? null : (\n <div className=\"hjm-section__description\">{description}</div>\n )}\n </div>\n {action === undefined ? null : <div className=\"hjm-section__action\">{action}</div>}\n </header>\n ) : null}\n <div className=\"hjm-section__content\">{children}</div>\n </section>\n );\n});\n\nexport type { GridGap };\nexport type { AspectRatioValue, ContainerGutter, ContainerSize };\n"]}
|
|
1
|
+
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../src/layout.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\n// Layout renderers read profile context; declaring this granular entry keeps server-owned guide text outside the client graph.\n// Root-barrel marking would also move unrelated exports; see docs/qa/2026-10-07-rsc-profile-boundary.md.\nimport { useDesignProfileDefaults } from \"./internal.js\";\nimport {\n resolveGridLayout,\n type GridDescriptor,\n type GridGap,\n} from \"@hjmds/design-contracts/grid\";\nimport {\n resolveAspectRatioDescriptor,\n type AspectRatioValue,\n} from \"@hjmds/design-contracts/components/aspect-ratio\";\nimport {\n resolveContainerDescriptor,\n type ContainerGutter,\n type ContainerSize,\n} from \"@hjmds/design-contracts/components/container\";\nimport {\n layoutRecipe,\n validateLayoutWebDescriptor,\n type LayoutSidebarDescriptor,\n type LayoutSidebarRole,\n} from \"@hjmds/design-contracts/components/layout\";\nimport {\n surfaceDefaults,\n surfaceGeometry,\n surfaceRecipe,\n type SurfacePadding,\n type SurfaceRadius,\n type SurfaceTone,\n} from \"@hjmds/design-contracts/recipes/base\";\nimport {\n resolveTextDefaultWeight,\n stackRecipe,\n textRecipe,\n type StackAlign,\n type StackAxis,\n type StackGap,\n type StackJustify,\n type TextEmphasis,\n type TextTone,\n} from \"@hjmds/design-contracts/recipes\";\nimport { numeric as numericVariants, resolveTextFontRole, typography, validateElevationStep, type ElevationStep, type FontRole, type NumericVariant, type TextVariant } from \"@hjmds/design-contracts/foundations\";\nimport {\n createElement,\n forwardRef,\n useId,\n useRef,\n type AnchorHTMLAttributes,\n type HTMLAttributes,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport {\n classNames,\n composeRefs,\n useElementWidth,\n useWindowWidth,\n} from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type {\n SurfacePadding,\n SurfaceRadius,\n SurfaceTone,\n} from \"@hjmds/design-contracts/recipes/base\";\nexport type {\n StackAlign,\n StackAxis,\n StackGap,\n StackJustify,\n TextEmphasis,\n TextTone,\n} from \"@hjmds/design-contracts/recipes\";\n\ntype LayoutRegionProps = Omit<\n HTMLAttributes<HTMLElement>,\n \"children\" | \"role\"\n>;\n\ntype LayoutSidebarBase = Readonly<{\n children: ReactNode;\n role: LayoutSidebarRole;\n label: string;\n landmarkProps?: Omit<LayoutRegionProps, \"aria-label\">;\n landmarkRef?: Ref<HTMLElement>;\n}>;\n\n/**\n * A persistent sidebar is rendered in the shell grid. An overlay sidebar is\n * deliberately handed to the product's SidePanel (or equivalent) through\n * `renderOverlay`; Layout never owns a second open/dismiss lifecycle.\n */\nexport type LayoutSidebar =\n | (LayoutSidebarBase &\n Readonly<{\n mode: \"persistent\";\n renderOverlay?: never;\n }>)\n | (LayoutSidebarBase &\n Readonly<{\n mode: \"overlay\";\n renderOverlay(sidebarLandmark: ReactElement): ReactNode;\n }>);\n\nexport type LayoutProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> &\n Readonly<{\n children: ReactNode;\n header?: ReactNode;\n footer?: ReactNode;\n sidebar?: LayoutSidebar;\n skipLinkLabel?: string;\n /** Stable product id for deep links; a hydration-safe id is generated when omitted. */\n mainId?: string;\n mainRef?: Ref<HTMLElement>;\n headerProps?: LayoutRegionProps;\n mainProps?: Omit<LayoutRegionProps, \"id\" | \"tabIndex\">;\n footerProps?: LayoutRegionProps;\n skipLinkProps?: Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n \"children\" | \"href\"\n >;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nfunction hasRegionContent(content: ReactNode | undefined): boolean {\n return content !== undefined && content !== null && content !== false;\n}\n\nfunction assertMainId(id: string): void {\n if (id.trim().length === 0) {\n throw new TypeError(\"Layout mainId must not be empty\");\n }\n if (/\\s/u.test(id)) {\n throw new TypeError(\"Layout mainId must not contain whitespace\");\n }\n}\n\n/** Accessible Web app shell with real landmarks and bypass navigation. */\nexport const Layout = forwardRef<HTMLDivElement, LayoutProps>(function Layout(\n {\n children,\n header,\n footer,\n sidebar,\n skipLinkLabel,\n mainId: mainIdProp,\n mainRef: forwardedMainRef,\n headerProps,\n mainProps,\n footerProps,\n skipLinkProps,\n className,\n layoutStyle,\n ...props\n },\n ref,\n) {\n const generatedId = `hjm-main-${useId().replaceAll(\":\", \"\")}`;\n const internalMainRef = useRef<HTMLElement>(null);\n const mainId = mainIdProp ?? generatedId;\n assertMainId(mainId);\n\n const hasHeader = hasRegionContent(header);\n const hasFooter = hasRegionContent(footer);\n const descriptor = {\n ...(hasHeader ? { hasHeader: true } : {}),\n ...(hasFooter ? { hasFooter: true } : {}),\n ...(sidebar === undefined\n ? {}\n : {\n sidebar: {\n role: sidebar.role,\n mode: sidebar.mode,\n label: sidebar.label,\n } satisfies LayoutSidebarDescriptor,\n }),\n ...(skipLinkLabel === undefined ? {} : { skipLinkLabel }),\n };\n validateLayoutWebDescriptor(descriptor);\n\n if (\n sidebar?.mode === \"overlay\" &&\n typeof sidebar.renderOverlay !== \"function\"\n ) {\n throw new TypeError(\n \"Layout overlay sidebar requires renderOverlay so SidePanel owns its lifecycle\",\n );\n }\n\n const {\n className: headerClassName,\n ...restHeaderProps\n } = headerProps ?? {};\n const {\n className: mainClassName,\n style: mainStyle,\n ...restMainProps\n } = mainProps ?? {};\n const {\n className: footerClassName,\n ...restFooterProps\n } = footerProps ?? {};\n const {\n className: skipLinkClassName,\n onClick: onSkipLinkClick,\n ...restSkipLinkProps\n } = skipLinkProps ?? {};\n\n let sidebarNode: ReactNode;\n if (sidebar !== undefined) {\n const {\n className: sidebarClassName,\n style: sidebarStyle,\n ...restSidebarProps\n } = sidebar.landmarkProps ?? {};\n const sidebarLandmark = createElement(\n sidebar.role === \"navigation\" ? \"nav\" : \"aside\",\n {\n ...restSidebarProps,\n ref: sidebar.landmarkRef,\n className: classNames(\"hjm-layout__sidebar\", sidebarClassName),\n \"aria-label\": sidebar.label,\n \"data-mode\": sidebar.mode,\n style: {\n ...(sidebar.mode === \"persistent\"\n ? { inlineSize: layoutRecipe.sidebar.width }\n : {}),\n ...sidebarStyle,\n },\n },\n sidebar.children,\n );\n sidebarNode = sidebar.mode === \"overlay\"\n ? sidebar.renderOverlay(sidebarLandmark)\n : sidebarLandmark;\n }\n\n const moveFocusToMain = (event: MouseEvent<HTMLAnchorElement>) => {\n onSkipLinkClick?.(event);\n if (event.defaultPrevented) return;\n const main = internalMainRef.current;\n if (main === null) return;\n event.preventDefault();\n const url = new URL(window.location.href);\n url.hash = mainId;\n window.history.replaceState(window.history.state, \"\", url);\n main.focus({ preventScroll: true });\n main.scrollIntoView?.({ block: \"start\" });\n };\n\n return (\n <div\n {...props}\n style={{ ...props.style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-layout\", className)}\n data-hjm-component=\"Layout\"\n data-sidebar-mode={sidebar?.mode ?? \"none\"}\n >\n {skipLinkLabel === undefined ? null : (\n <a\n {...restSkipLinkProps}\n href={`#${mainId}`}\n className={classNames(\n \"hjm-layout__skip-link\",\n skipLinkClassName,\n )}\n onClick={moveFocusToMain}\n >\n {skipLinkLabel}\n </a>\n )}\n {hasHeader ? (\n <header\n {...restHeaderProps}\n className={classNames(\"hjm-layout__header\", headerClassName)}\n >\n {header}\n </header>\n ) : null}\n {sidebarNode}\n <main\n {...restMainProps}\n ref={composeRefs(internalMainRef, forwardedMainRef)}\n id={mainId}\n className={classNames(\"hjm-layout__main\", mainClassName)}\n tabIndex={-1}\n style={{\n maxInlineSize: layoutRecipe.main.maxWidth,\n paddingInline: layoutRecipe.main.paddingHorizontal,\n ...mainStyle,\n }}\n >\n {children}\n </main>\n {hasFooter ? (\n <footer\n {...restFooterProps}\n className={classNames(\"hjm-layout__footer\", footerClassName)}\n >\n {footer}\n </footer>\n ) : null}\n </div>\n );\n});\n\nexport type TextProps = Omit<HTMLAttributes<HTMLElement>, \"children\" | \"color\"> &\n Readonly<{\n children: ReactNode;\n as?: \"span\" | \"p\" | \"div\" | \"strong\" | \"small\";\n variant?: TextVariant;\n /** Overrides the variant family role; never changes its semantic element or metrics. */\n fontRole?: FontRole;\n tone?: TextTone;\n /**\n * Product-owned color role (team, sentiment, chart series) replacing the `tone` color while the HJM variant\n * metrics and font face stay. Mirrors Native, where dropping to a raw text host lost the face (2026-10-18).\n * Replaces the legacy HTML `color` attribute type, which no browser applies to text. Contrast is the product's.\n */\n color?: string;\n /** Digit spacing; `tabular` keeps changing numbers (scores, timers, counts) from shifting the layout. */\n numeric?: NumericVariant;\n emphasis?: TextEmphasis;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Text = forwardRef<HTMLElement, TextProps>(function Text(\n {\n as = \"span\",\n variant = textRecipe.defaults.variant,\n fontRole,\n tone = textRecipe.defaults.tone,\n color,\n numeric,\n emphasis: suppliedEmphasis,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n const profile = useDesignProfileDefaults();\n const emphasis = suppliedEmphasis ?? textRecipe.defaults.emphasis;\n const defaultWeight = suppliedEmphasis === undefined\n ? resolveTextDefaultWeight(variant, profile?.tokens.typography ?? typography, profile !== undefined)\n : undefined;\n return createElement(as, {\n ...props,\n ref,\n className: classNames(\"hjm-text\", className),\n \"data-variant\": variant,\n \"data-font-role\": resolveTextFontRole(variant, fontRole ?? (props.role === \"heading\" ? \"display\" : undefined)),\n \"data-tone\": tone,\n \"data-emphasis\": emphasis,\n // The variant default weight goes first so caller `style`/placement win, matching Native's style order\n // (it used to be spread last and overrode an explicit style weight under a profile).\n \"data-numeric\": numeric,\n style: {\n ...(defaultWeight === undefined ? {} : { fontWeight: defaultWeight }),\n ...(color === undefined ? {} : { color }),\n ...(numeric === undefined ? {} : { fontVariantNumeric: numericVariants[numeric] }),\n ...style,\n ...layoutStyle,\n },\n });\n});\n\nexport type SurfaceProps = HTMLAttributes<HTMLElement> &\n Readonly<{\n as?: \"div\" | \"section\" | \"article\" | \"button\";\n /** Native button host used by interactive Card; passive surfaces remain divs. */\n type?: \"button\";\n disabled?: boolean;\n tone?: SurfaceTone;\n bordered?: boolean;\n padding?: SurfacePadding;\n radius?: SurfaceRadius;\n /**\n * Shadow token step (`--hjm-shadow-*`). Omitted, the tone decides (raised → raised, others none); `none` removes\n * the raised shadow. An elevated surface does not clip its content, as the raised tone.\n */\n elevation?: ElevationStep;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Surface = forwardRef<HTMLElement, SurfaceProps>(function Surface(\n {\n as = \"div\",\n tone = surfaceDefaults.tone,\n bordered,\n padding = surfaceDefaults.padding,\n radius = surfaceDefaults.radius,\n elevation,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n const contract = surfaceRecipe[tone];\n if (elevation !== undefined) validateElevationStep(elevation, \"Surface\");\n const lifted = elevation === undefined ? contract.elevated : elevation !== \"none\";\n return createElement(as, {\n ...props,\n ref,\n className: classNames(\"hjm-surface\", className),\n \"data-tone\": tone,\n // Canvas framing is the default; preserve the caller's explicit border opt-out.\n \"data-bordered\": bordered ?? (surfaceDefaults.bordered || contract.borderAlways),\n \"data-elevated\": lifted,\n \"data-elevation\": elevation,\n \"data-clips\": contract.clipsContent && !lifted,\n \"data-padding\": padding,\n \"data-radius\": radius,\n style: {\n padding: surfaceGeometry.paddings[padding],\n borderRadius: `var(--hjm-radius-${radius})`,\n ...style,\n ...layoutStyle,\n },\n });\n});\n\nexport type StackProps = HTMLAttributes<HTMLDivElement> &\n Readonly<{\n axis?: StackAxis;\n gap?: StackGap;\n align?: StackAlign;\n justify?: StackJustify;\n wrap?: boolean;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nconst justifyValues = {\n start: \"flex-start\",\n center: \"center\",\n end: \"flex-end\",\n between: \"space-between\",\n} as const;\n\nexport const Stack = forwardRef<HTMLDivElement, StackProps>(function Stack(\n {\n axis = stackRecipe.defaults.axis,\n gap = stackRecipe.defaults.gap,\n align = stackRecipe.defaults.align,\n justify = stackRecipe.defaults.justify,\n wrap = stackRecipe.defaults.wrap,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n return (\n <div\n {...props}\n ref={ref}\n className={classNames(\"hjm-stack\", className)}\n data-axis={axis}\n data-gap={gap}\n style={{\n display: \"flex\",\n flexDirection: stackRecipe.axes[axis],\n gap: stackRecipe.gaps[gap],\n alignItems: align === \"start\" || align === \"end\" ? `flex-${align}` : align,\n justifyContent: justifyValues[justify],\n flexWrap: wrap ? \"wrap\" : \"nowrap\",\n ...style,\n ...layoutStyle,\n }}\n />\n );\n});\n\nexport type ContainerProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> &\n Readonly<{\n children?: ReactNode;\n size?: ContainerSize;\n gutter?: ContainerGutter;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\n/** A centered, token-guttered content boundary shared with Native large screens. */\nexport const Container = forwardRef<HTMLDivElement, ContainerProps>(function Container(\n { size, gutter, className, layoutStyle, style, ...props },\n ref,\n) {\n const resolved = resolveContainerDescriptor({\n ...(size === undefined ? {} : { size }),\n ...(gutter === undefined ? {} : { gutter }),\n });\n return (\n <div\n {...props}\n ref={ref}\n className={classNames(\"hjm-container\", className)}\n data-size={resolved.size}\n data-gutter={resolved.gutter}\n style={{\n maxInlineSize: resolved.maxWidth ?? undefined,\n paddingInline: resolved.paddingInline,\n ...style,\n ...layoutStyle,\n }}\n />\n );\n});\n\nexport type AspectRatioProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> &\n Readonly<{\n children?: ReactNode;\n ratio?: AspectRatioValue;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\n/** Responsive media frame. Products retain object-fit, crop, and content semantics. */\nexport const AspectRatio = forwardRef<HTMLDivElement, AspectRatioProps>(function AspectRatio(\n { ratio, className, layoutStyle, style, ...props },\n ref,\n) {\n const resolved = resolveAspectRatioDescriptor(\n ratio === undefined ? {} : { ratio },\n );\n return (\n <div\n {...props}\n ref={ref}\n className={classNames(\"hjm-aspect-ratio\", className)}\n data-ratio={resolved.source}\n style={{ ...layoutStyle, aspectRatio: resolved.ratio, ...style }}\n />\n );\n});\n\n// No `layoutStyle`: the element is clipped to 1px by design, so placement has no visible effect.\nexport type VisuallyHiddenProps = HTMLAttributes<HTMLSpanElement> &\n Readonly<{ children: ReactNode }>;\n\n/** Keeps meaningful copy available to assistive technology without visible layout. */\nexport const VisuallyHidden = forwardRef<HTMLSpanElement, VisuallyHiddenProps>(\n function VisuallyHidden({ className, ...props }, ref) {\n return (\n <span\n {...props}\n ref={ref}\n className={classNames(\"hjm-visually-hidden\", className)}\n />\n );\n },\n);\n\nexport type GridProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> &\n Pick<GridDescriptor, \"columns\" | \"gap\" | \"minColumnWidth\"> &\n Readonly<{\n children?: ReactNode;\n /** Test/SSR override. Browser renderers otherwise observe window.innerWidth. */\n windowWidth?: number;\n /** Container measurement override; ResizeObserver is used when omitted. */\n availableWidth?: number;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Grid = forwardRef<HTMLDivElement, GridProps>(function Grid(\n {\n columns,\n gap,\n minColumnWidth,\n windowWidth,\n availableWidth,\n className,\n layoutStyle,\n style,\n ...props\n },\n forwardedRef,\n) {\n const browserWindowWidth = useWindowWidth();\n const [measuredWidth, gridRef] = useElementWidth(forwardedRef);\n const compactSsrWidth = 320;\n const effectiveWindowWidth =\n windowWidth ??\n (browserWindowWidth > 0 ? browserWindowWidth : compactSsrWidth);\n const effectiveAvailableWidth =\n availableWidth ??\n (measuredWidth !== undefined && measuredWidth > 0\n ? measuredWidth\n : effectiveWindowWidth);\n const descriptor: GridDescriptor = {\n columns,\n ...(gap === undefined ? {} : { gap }),\n ...(minColumnWidth === undefined ? {} : { minColumnWidth }),\n };\n const layout = resolveGridLayout(descriptor, {\n windowWidth: effectiveWindowWidth,\n availableWidth: effectiveAvailableWidth,\n });\n\n return (\n <div\n {...props}\n ref={gridRef}\n className={classNames(\"hjm-grid\", className)}\n data-window-class={layout.windowClass}\n data-columns={layout.columns}\n data-requested-columns={layout.requestedColumns}\n data-state={layout.columns < layout.requestedColumns ? \"collapsed\" : \"resolved\"}\n style={{\n display: \"grid\",\n gridTemplateColumns: `repeat(${layout.columns}, minmax(0, 1fr))`,\n rowGap: layout.rowGap,\n columnGap: layout.columnGap,\n ...style,\n ...layoutStyle,\n }}\n />\n );\n});\n\nexport type SectionProps = Omit<HTMLAttributes<HTMLElement>, \"children\" | \"title\"> &\n Readonly<{\n title?: ReactNode;\n description?: ReactNode;\n action?: ReactNode;\n children: ReactNode;\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\n/** Large-text-safe semantic content section with an optional header action. */\nexport const Section = forwardRef<HTMLElement, SectionProps>(function Section(\n {\n title,\n description,\n action,\n children,\n headingLevel = 2,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n const hasHeader = title !== undefined || description !== undefined || action !== undefined;\n return (\n <section {...props} style={{ ...style, ...layoutStyle }} ref={ref} className={classNames(\"hjm-section\", className)}>\n {hasHeader ? (\n <header className=\"hjm-section__header\">\n <div className=\"hjm-section__copy\">\n {title === undefined ? null : createElement(\n `h${headingLevel}`,\n { className: \"hjm-section__title\" },\n title,\n )}\n {description === undefined ? null : (\n <div className=\"hjm-section__description\">{description}</div>\n )}\n </div>\n {action === undefined ? null : <div className=\"hjm-section__action\">{action}</div>}\n </header>\n ) : null}\n <div className=\"hjm-section__content\">{children}</div>\n </section>\n );\n});\n\nexport type { GridGap };\nexport type { AspectRatioValue, ContainerGutter, ContainerSize };\n"]}
|
package/dist/mentions.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mentions.d.ts","sourceRoot":"","sources":["../src/mentions.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mentions.d.ts","sourceRoot":"","sources":["../src/mentions.tsx"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,oBAAoB,EAC1B,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAQL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAI1D,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC,CAAC;AAEH,MAAM,MAAM,aAAa,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM,IACzD,IAAI,CAAC,aAAa,EAAE,OAAO,GAAG,cAAc,GAAG,UAAU,GAAG,UAAU,CAAC,GACvE,QAAQ,CAAC;IACP,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,QAAQ,EAAE,SAAS,oBAAoB,CAAC,SAAS,CAAC,EAAE,CAAC;IACrD,+EAA+E;IAC/E,UAAU,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACxC,0EAA0E;IAC1E,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,SAAS,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IACvE,yEAAyE;IACzE,YAAY,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,gBAAgB,KAAK,SAAS,CAAC;CAC9D,CAAC,CAAC;AAEL,eAAO,MAAM,QAAQ,EAyJf,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM,EACtC,KAAK,EAAE,aAAa,CAAC,SAAS,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAA;CAAE,KACvE,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC"}
|
package/dist/mentions.js
CHANGED
package/dist/mentions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mentions.js","sourceRoot":"","sources":["../src/mentions.tsx"],"names":[],"mappings":"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","sourcesContent":["import { layer } from \"@hjmds/design-contracts/foundations\";\nimport { comboboxRecipe } from \"@hjmds/design-contracts/recipes\";\nimport {\n findActiveMentionTrigger,\n resolveMentionInsertion,\n type MentionMatch,\n type MentionTriggerConfig,\n} from \"@hjmds/design-contracts/components/mentions\";\nimport {\n forwardRef,\n useEffect,\n useId,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type ReactNode,\n} from \"react\";\nimport { TextArea, type TextAreaProps } from \"./forms.js\";\nimport { classNames, composeRefs } from \"./internal.js\";\nimport { AnchoredPortal, useAnchoredPopup } from \"./portal.js\";\n\nexport type MentionCandidate = Readonly<{\n id: string;\n label: string;\n /** Text inserted after the trigger character; defaults to `label`. */\n insertText?: string;\n description?: string;\n}>;\n\nexport type MentionsProps<TriggerId extends string = string> =\n Omit<TextAreaProps, \"value\" | \"defaultValue\" | \"onChange\" | \"children\"> &\n Readonly<{\n value: string;\n onValueChange: (value: string) => void;\n triggers: readonly MentionTriggerConfig<TriggerId>[];\n /** Candidates for the active query; the product owns filtering and loading. */\n candidates: readonly MentionCandidate[];\n /** Fires whenever the active trigger match changes, including to null. */\n onMentionQueryChange?: (match: MentionMatch<TriggerId> | null) => void;\n /** Localized message shown when the popup is open with no candidates. */\n emptyMessage: string;\n /** Localized accessible name for the candidate list. */\n listLabel: string;\n renderCandidate?: (candidate: MentionCandidate) => ReactNode;\n }>;\n\nexport const Mentions = forwardRef(function Mentions<TriggerId extends string = string>(\n {\n value,\n onValueChange,\n triggers,\n candidates,\n onMentionQueryChange,\n emptyMessage,\n listLabel,\n renderCandidate,\n className,\n // Inherited from TextAreaProps; taken here so placement moves the whole\n // mentions block (field + candidate popup anchor), not only the inner field.\n layoutStyle,\n ...textAreaProps\n }: MentionsProps<TriggerId>,\n forwardedRef: React.Ref<HTMLTextAreaElement>,\n) {\n const inputRef = useRef<HTMLTextAreaElement>(null);\n const [match, setMatch] = useState<MentionMatch<TriggerId> | null>(null);\n const [activeIndex, setActiveIndex] = useState(0);\n const [list, setList] = useState<HTMLDivElement | null>(null);\n const id = `${useId().replaceAll(\":\", \"\")}-mentions`;\n const unavailable = textAreaProps.disabled || textAreaProps.readOnly;\n const open = match !== null && !unavailable;\n const activeCandidate = candidates[Math.min(activeIndex, Math.max(candidates.length - 1, 0))];\n\n const notifyRef = useRef(onMentionQueryChange);\n notifyRef.current = onMentionQueryChange;\n useEffect(() => { notifyRef.current?.(match); }, [match]);\n\n const syncMatch = (text: string, cursor: number) => {\n // The contract owns trigger detection, including \"a space closes it\" and\n // \"the nearer trigger wins\"; this component only reports the cursor.\n const next = unavailable ? null : findActiveMentionTrigger(text, cursor, triggers);\n setMatch((previous) => (previous?.triggerStart === next?.triggerStart && previous?.query === next?.query ? previous : next));\n if (next === null || next.query !== match?.query) setActiveIndex(0);\n };\n const commit = (candidate: MentionCandidate) => {\n const input = inputRef.current;\n if (unavailable || !match || !input) return;\n const result = resolveMentionInsertion(value, match, input.selectionStart ?? value.length, candidate.insertText ?? candidate.label);\n onValueChange(result.text);\n setMatch(null);\n queueMicrotask(() => {\n input.focus();\n input.setSelectionRange(result.cursorPosition, result.cursorPosition);\n });\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n if (!open || event.defaultPrevented || event.nativeEvent.isComposing || event.keyCode === 229) return;\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n if (candidates.length === 0) return;\n event.preventDefault();\n setActiveIndex((previous) => {\n const next = event.key === \"ArrowDown\" ? previous + 1 : previous - 1;\n return (next + candidates.length) % candidates.length;\n });\n return;\n }\n if (event.key === \"Escape\") {\n // Dismissing the popup must not touch the text the user already typed.\n event.preventDefault();\n event.stopPropagation();\n setMatch(null);\n return;\n }\n if (event.key === \"Enter\" && activeCandidate && candidates.length > 0) {\n event.preventDefault();\n commit(activeCandidate);\n }\n };\n\n const position = useAnchoredPopup(inputRef, open ? list : null, {\n placement: \"bottom\", align: \"start\", matchAnchorWidth: true, zIndex: layer.dropdown,\n // The candidate list is Combobox's popover contract verbatim (mentions.ts), so its offset and edge padding are\n // comboboxRecipe.popover's 8/8. Until 2026-10-06 the helper defaults (8 and 16) applied, a Web-only 16 edge.\n gap: comboboxRecipe.popover.sideOffset,\n viewportPadding: comboboxRecipe.popover.collisionPadding,\n });\n\n return (\n <div className={classNames(\"hjm-mentions\", className)} style={layoutStyle}>\n <TextArea\n {...textAreaProps}\n ref={composeRefs(inputRef, forwardedRef)}\n value={value}\n role=\"combobox\"\n aria-expanded={open}\n aria-controls={open ? id : undefined}\n aria-autocomplete=\"list\"\n aria-activedescendant={open && activeCandidate ? `${id}-${activeCandidate.id}` : undefined}\n onChange={(event) => {\n onValueChange(event.target.value);\n syncMatch(event.target.value, event.target.selectionStart ?? event.target.value.length);\n }}\n onKeyUp={(event) => {\n // Caret moves without an edit (arrows, clicks) change which trigger is\n // active, so the match is re-read from the caret, not only from input.\n textAreaProps.onKeyUp?.(event);\n // Escape keyup must not reopen the token dismissed on keydown.\n if (event.defaultPrevented || event.key === \"Escape\" || event.nativeEvent.isComposing || event.keyCode === 229) return;\n if (open && (event.key === \"ArrowDown\" || event.key === \"ArrowUp\")) return;\n const input = event.currentTarget;\n syncMatch(input.value, input.selectionStart ?? input.value.length);\n }}\n onClick={(event) => {\n textAreaProps.onClick?.(event);\n if (event.defaultPrevented) return;\n const input = event.currentTarget;\n syncMatch(input.value, input.selectionStart ?? input.value.length);\n }}\n onBlur={(event) => { textAreaProps.onBlur?.(event); setMatch(null); }}\n onKeyDown={(event) => { textAreaProps.onKeyDown?.(event); onKeyDown(event); }}\n />\n {open ? (\n <AnchoredPortal anchorRef={inputRef}>\n <div\n ref={setList}\n id={id}\n role=\"listbox\"\n aria-label={listLabel}\n className=\"hjm-mentions__list\"\n style={position.style as CSSProperties}\n >\n {candidates.length === 0 ? (\n <p className=\"hjm-mentions__empty\" role=\"status\">{emptyMessage}</p>\n ) : candidates.map((candidate, index) => (\n <div\n key={candidate.id}\n id={`${id}-${candidate.id}`}\n role=\"option\"\n aria-selected={candidate.id === activeCandidate?.id}\n className=\"hjm-mentions__option\"\n // Pointer commit must not blur the textarea first, or the caret\n // position the insertion depends on would already be gone.\n onMouseDown={(event) => { event.preventDefault(); commit(candidate); }}\n onMouseEnter={() => setActiveIndex(index)}\n >\n {renderCandidate?.(candidate) ?? (\n <>\n <span>{candidate.label}</span>\n {candidate.description ? <span className=\"hjm-mentions__description\">{candidate.description}</span> : null}\n </>\n )}\n </div>\n ))}\n </div>\n </AnchoredPortal>\n ) : null}\n </div>\n );\n}) as <TriggerId extends string = string>(\n props: MentionsProps<TriggerId> & { ref?: React.Ref<HTMLTextAreaElement> },\n) => React.ReactElement | null;\n"]}
|
|
1
|
+
{"version":3,"file":"mentions.js","sourceRoot":"","sources":["../src/mentions.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EACL,wBAAwB,EACxB,uBAAuB,GAGxB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EACL,UAAU,EACV,SAAS,EACT,KAAK,EACL,MAAM,EACN,QAAQ,GAIT,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,QAAQ,EAAsB,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AA2B/D,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC,SAAS,QAAQ,CAClD,EACE,KAAK,EACL,aAAa,EACb,QAAQ,EACR,UAAU,EACV,oBAAoB,EACpB,YAAY,EACZ,SAAS,EACT,eAAe,EACf,SAAS;AACT,wEAAwE;AACxE,6EAA6E;AAC7E,WAAW,EACX,GAAG,aAAa,EACS,EAC3B,YAA4C;IAE5C,MAAM,QAAQ,GAAG,MAAM,CAAsB,IAAI,CAAC,CAAC;IACnD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAiC,IAAI,CAAC,CAAC;IACzE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAClD,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAwB,IAAI,CAAC,CAAC;IAC9D,MAAM,EAAE,GAAG,GAAG,KAAK,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,WAAW,CAAC;IACrD,MAAM,WAAW,GAAG,aAAa,CAAC,QAAQ,IAAI,aAAa,CAAC,QAAQ,CAAC;IACrE,MAAM,IAAI,GAAG,KAAK,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC;IAC5C,MAAM,eAAe,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAE9F,MAAM,SAAS,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAC/C,SAAS,CAAC,OAAO,GAAG,oBAAoB,CAAC;IACzC,SAAS,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAE1D,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,MAAc,EAAE,EAAE;QACjD,yEAAyE;QACzE,qEAAqE;QACrE,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QACnF,QAAQ,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,EAAE,YAAY,IAAI,QAAQ,EAAE,KAAK,KAAK,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7H,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,EAAE,KAAK;YAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IACtE,CAAC,CAAC;IACF,MAAM,MAAM,GAAG,CAAC,SAA2B,EAAE,EAAE;QAC7C,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC;QAC/B,IAAI,WAAW,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK;YAAE,OAAO;QAC5C,MAAM,MAAM,GAAG,uBAAuB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,UAAU,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC;QACpI,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3B,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,cAAc,CAAC,GAAG,EAAE;YAClB,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,CAAC,KAAyC,EAAE,EAAE;QAC9D,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,gBAAgB,IAAI,KAAK,CAAC,WAAW,CAAC,WAAW,IAAI,KAAK,CAAC,OAAO,KAAK,GAAG;YAAE,OAAO;QACtG,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YACzD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YACpC,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,cAAc,CAAC,CAAC,QAAQ,EAAE,EAAE;gBAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,KAAK,WAAW,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrE,OAAO,CAAC,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;YACxD,CAAC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC3B,uEAAuE;YACvE,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,QAAQ,CAAC,IAAI,CAAC,CAAC;YACf,OAAO;QACT,CAAC;QACD,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,IAAI,eAAe,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtE,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,MAAM,CAAC,eAAe,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;QAC9D,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,QAAQ;QACnF,+GAA+G;QAC/G,6GAA6G;QAC7G,GAAG,EAAE,cAAc,CAAC,OAAO,CAAC,UAAU;QACtC,eAAe,EAAE,cAAc,CAAC,OAAO,CAAC,gBAAgB;KACzD,CAAC,CAAC;IAEH,OAAO,CACL,eAAK,SAAS,EAAE,UAAU,CAAC,cAAc,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,WAAW,aACvE,KAAC,QAAQ,OACH,aAAa,EACjB,GAAG,EAAE,WAAW,CAAC,QAAQ,EAAE,YAAY,CAAC,EACxC,KAAK,EAAE,KAAK,EACZ,IAAI,EAAC,UAAU,mBACA,IAAI,mBACJ,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,uBAClB,MAAM,2BACD,IAAI,IAAI,eAAe,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,eAAe,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,EAC1F,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;oBAClB,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBAClC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,cAAc,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBAC1F,CAAC,EACD,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;oBACjB,uEAAuE;oBACvE,uEAAuE;oBACvE,aAAa,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;oBAC/B,+DAA+D;oBAC/D,IAAI,KAAK,CAAC,gBAAgB,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,WAAW,CAAC,WAAW,IAAI,KAAK,CAAC,OAAO,KAAK,GAAG;wBAAE,OAAO;oBACvH,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,WAAW,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC;wBAAE,OAAO;oBAC3E,MAAM,KAAK,GAAG,KAAK,CAAC,aAAa,CAAC;oBAClC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACrE,CAAC,EACD,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;oBACjB,aAAa,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;oBAC/B,IAAI,KAAK,CAAC,gBAAgB;wBAAE,OAAO;oBACnC,MAAM,KAAK,GAAG,KAAK,CAAC,aAAa,CAAC;oBAClC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACrE,CAAC,EACD,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EACrE,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,aAAa,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAC7E,EACD,IAAI,CAAC,CAAC,CAAC,CACN,KAAC,cAAc,IAAC,SAAS,EAAE,QAAQ,YACjC,cACE,GAAG,EAAE,OAAO,EACZ,EAAE,EAAE,EAAE,EACN,IAAI,EAAC,SAAS,gBACF,SAAS,EACrB,SAAS,EAAC,oBAAoB,EAC9B,KAAK,EAAE,QAAQ,CAAC,KAAsB,YAErC,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACzB,YAAG,SAAS,EAAC,qBAAqB,EAAC,IAAI,EAAC,QAAQ,YAAE,YAAY,GAAK,CACpE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC,CACvC,cAEE,EAAE,EAAE,GAAG,EAAE,IAAI,SAAS,CAAC,EAAE,EAAE,EAC3B,IAAI,EAAC,QAAQ,mBACE,SAAS,CAAC,EAAE,KAAK,eAAe,EAAE,EAAE,EACnD,SAAS,EAAC,sBAAsB;wBAChC,gEAAgE;wBAChE,2DAA2D;wBAC3D,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EACtE,YAAY,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,YAExC,eAAe,EAAE,CAAC,SAAS,CAAC,IAAI,CAC/B,8BACE,yBAAO,SAAS,CAAC,KAAK,GAAQ,EAC7B,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,2BAA2B,YAAE,SAAS,CAAC,WAAW,GAAQ,CAAC,CAAC,CAAC,IAAI,IACzG,CACJ,IAfI,SAAS,CAAC,EAAE,CAgBb,CACP,CAAC,GACE,GACS,CAClB,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC,CAE6B,CAAC","sourcesContent":["\"use client\";\n\nimport { layer } from \"@hjmds/design-contracts/foundations\";\nimport { comboboxRecipe } from \"@hjmds/design-contracts/recipes\";\nimport {\n findActiveMentionTrigger,\n resolveMentionInsertion,\n type MentionMatch,\n type MentionTriggerConfig,\n} from \"@hjmds/design-contracts/components/mentions\";\nimport {\n forwardRef,\n useEffect,\n useId,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type ReactNode,\n} from \"react\";\nimport { TextArea, type TextAreaProps } from \"./forms.js\";\nimport { classNames, composeRefs } from \"./internal.js\";\nimport { AnchoredPortal, useAnchoredPopup } from \"./portal.js\";\n\nexport type MentionCandidate = Readonly<{\n id: string;\n label: string;\n /** Text inserted after the trigger character; defaults to `label`. */\n insertText?: string;\n description?: string;\n}>;\n\nexport type MentionsProps<TriggerId extends string = string> =\n Omit<TextAreaProps, \"value\" | \"defaultValue\" | \"onChange\" | \"children\"> &\n Readonly<{\n value: string;\n onValueChange: (value: string) => void;\n triggers: readonly MentionTriggerConfig<TriggerId>[];\n /** Candidates for the active query; the product owns filtering and loading. */\n candidates: readonly MentionCandidate[];\n /** Fires whenever the active trigger match changes, including to null. */\n onMentionQueryChange?: (match: MentionMatch<TriggerId> | null) => void;\n /** Localized message shown when the popup is open with no candidates. */\n emptyMessage: string;\n /** Localized accessible name for the candidate list. */\n listLabel: string;\n renderCandidate?: (candidate: MentionCandidate) => ReactNode;\n }>;\n\nexport const Mentions = forwardRef(function Mentions<TriggerId extends string = string>(\n {\n value,\n onValueChange,\n triggers,\n candidates,\n onMentionQueryChange,\n emptyMessage,\n listLabel,\n renderCandidate,\n className,\n // Inherited from TextAreaProps; taken here so placement moves the whole\n // mentions block (field + candidate popup anchor), not only the inner field.\n layoutStyle,\n ...textAreaProps\n }: MentionsProps<TriggerId>,\n forwardedRef: React.Ref<HTMLTextAreaElement>,\n) {\n const inputRef = useRef<HTMLTextAreaElement>(null);\n const [match, setMatch] = useState<MentionMatch<TriggerId> | null>(null);\n const [activeIndex, setActiveIndex] = useState(0);\n const [list, setList] = useState<HTMLDivElement | null>(null);\n const id = `${useId().replaceAll(\":\", \"\")}-mentions`;\n const unavailable = textAreaProps.disabled || textAreaProps.readOnly;\n const open = match !== null && !unavailable;\n const activeCandidate = candidates[Math.min(activeIndex, Math.max(candidates.length - 1, 0))];\n\n const notifyRef = useRef(onMentionQueryChange);\n notifyRef.current = onMentionQueryChange;\n useEffect(() => { notifyRef.current?.(match); }, [match]);\n\n const syncMatch = (text: string, cursor: number) => {\n // The contract owns trigger detection, including \"a space closes it\" and\n // \"the nearer trigger wins\"; this component only reports the cursor.\n const next = unavailable ? null : findActiveMentionTrigger(text, cursor, triggers);\n setMatch((previous) => (previous?.triggerStart === next?.triggerStart && previous?.query === next?.query ? previous : next));\n if (next === null || next.query !== match?.query) setActiveIndex(0);\n };\n const commit = (candidate: MentionCandidate) => {\n const input = inputRef.current;\n if (unavailable || !match || !input) return;\n const result = resolveMentionInsertion(value, match, input.selectionStart ?? value.length, candidate.insertText ?? candidate.label);\n onValueChange(result.text);\n setMatch(null);\n queueMicrotask(() => {\n input.focus();\n input.setSelectionRange(result.cursorPosition, result.cursorPosition);\n });\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n if (!open || event.defaultPrevented || event.nativeEvent.isComposing || event.keyCode === 229) return;\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n if (candidates.length === 0) return;\n event.preventDefault();\n setActiveIndex((previous) => {\n const next = event.key === \"ArrowDown\" ? previous + 1 : previous - 1;\n return (next + candidates.length) % candidates.length;\n });\n return;\n }\n if (event.key === \"Escape\") {\n // Dismissing the popup must not touch the text the user already typed.\n event.preventDefault();\n event.stopPropagation();\n setMatch(null);\n return;\n }\n if (event.key === \"Enter\" && activeCandidate && candidates.length > 0) {\n event.preventDefault();\n commit(activeCandidate);\n }\n };\n\n const position = useAnchoredPopup(inputRef, open ? list : null, {\n placement: \"bottom\", align: \"start\", matchAnchorWidth: true, zIndex: layer.dropdown,\n // The candidate list is Combobox's popover contract verbatim (mentions.ts), so its offset and edge padding are\n // comboboxRecipe.popover's 8/8. Until 2026-10-06 the helper defaults (8 and 16) applied, a Web-only 16 edge.\n gap: comboboxRecipe.popover.sideOffset,\n viewportPadding: comboboxRecipe.popover.collisionPadding,\n });\n\n return (\n <div className={classNames(\"hjm-mentions\", className)} style={layoutStyle}>\n <TextArea\n {...textAreaProps}\n ref={composeRefs(inputRef, forwardedRef)}\n value={value}\n role=\"combobox\"\n aria-expanded={open}\n aria-controls={open ? id : undefined}\n aria-autocomplete=\"list\"\n aria-activedescendant={open && activeCandidate ? `${id}-${activeCandidate.id}` : undefined}\n onChange={(event) => {\n onValueChange(event.target.value);\n syncMatch(event.target.value, event.target.selectionStart ?? event.target.value.length);\n }}\n onKeyUp={(event) => {\n // Caret moves without an edit (arrows, clicks) change which trigger is\n // active, so the match is re-read from the caret, not only from input.\n textAreaProps.onKeyUp?.(event);\n // Escape keyup must not reopen the token dismissed on keydown.\n if (event.defaultPrevented || event.key === \"Escape\" || event.nativeEvent.isComposing || event.keyCode === 229) return;\n if (open && (event.key === \"ArrowDown\" || event.key === \"ArrowUp\")) return;\n const input = event.currentTarget;\n syncMatch(input.value, input.selectionStart ?? input.value.length);\n }}\n onClick={(event) => {\n textAreaProps.onClick?.(event);\n if (event.defaultPrevented) return;\n const input = event.currentTarget;\n syncMatch(input.value, input.selectionStart ?? input.value.length);\n }}\n onBlur={(event) => { textAreaProps.onBlur?.(event); setMatch(null); }}\n onKeyDown={(event) => { textAreaProps.onKeyDown?.(event); onKeyDown(event); }}\n />\n {open ? (\n <AnchoredPortal anchorRef={inputRef}>\n <div\n ref={setList}\n id={id}\n role=\"listbox\"\n aria-label={listLabel}\n className=\"hjm-mentions__list\"\n style={position.style as CSSProperties}\n >\n {candidates.length === 0 ? (\n <p className=\"hjm-mentions__empty\" role=\"status\">{emptyMessage}</p>\n ) : candidates.map((candidate, index) => (\n <div\n key={candidate.id}\n id={`${id}-${candidate.id}`}\n role=\"option\"\n aria-selected={candidate.id === activeCandidate?.id}\n className=\"hjm-mentions__option\"\n // Pointer commit must not blur the textarea first, or the caret\n // position the insertion depends on would already be gone.\n onMouseDown={(event) => { event.preventDefault(); commit(candidate); }}\n onMouseEnter={() => setActiveIndex(index)}\n >\n {renderCandidate?.(candidate) ?? (\n <>\n <span>{candidate.label}</span>\n {candidate.description ? <span className=\"hjm-mentions__description\">{candidate.description}</span> : null}\n </>\n )}\n </div>\n ))}\n </div>\n </AnchoredPortal>\n ) : null}\n </div>\n );\n}) as <TriggerId extends string = string>(\n props: MentionsProps<TriggerId> & { ref?: React.Ref<HTMLTextAreaElement> },\n) => React.ReactElement | null;\n"]}
|
package/dist/menu-morph.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu-morph.d.ts","sourceRoot":"","sources":["../src/menu-morph.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"menu-morph.d.ts","sourceRoot":"","sources":["../src/menu-morph.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAQ,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC;;;;OAIG;IACH,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC;AAEF,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAgB,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,iBAAiB,+BAsFxI"}
|
package/dist/menu-morph.js
CHANGED
package/dist/menu-morph.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu-morph.js","sourceRoot":"","sources":["../src/menu-morph.tsx"],"names":[],"mappings":"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","sourcesContent":["import { resolveMenuTypeahead } from \"./menu-typeahead.js\";\nimport { Menu as Bloom } from \"bloom-menu\";\nimport { useEffect, useLayoutEffect, useRef, useState, type KeyboardEvent } from \"react\";\nimport { radius } from \"@hjmds/design-contracts/foundations\";\nimport { Button } from \"./actions.js\";\nimport { Icon } from \"./supplemental-display.js\";\nimport { Menu, type MenuItem } from \"./overlays.js\";\nimport { useHjmTheme } from \"./provider.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type MorphingMenuProps = {\n label: string;\n items: readonly MenuItem[];\n onAction?: (id: string) => void;\n disabled?: boolean;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n /**\n * Canonical layout-only placement. Applied to the morph root, or to the\n * canonical Menu's wrapper when reduced motion/RTL falls back to it, so\n * placement survives the switch.\n */\n layoutStyle?: HjmCompositionStyleProp;\n};\n\n/** Action-only morph presentation. Selection/async menus retain the full Menu. */\nexport function MorphingMenu({ label, items, onAction, disabled = false, open: controlled, onOpenChange, layoutStyle }: MorphingMenuProps) {\n const theme = useHjmTheme();\n const [localOpen, setLocalOpen] = useState(false);\n const open = controlled ?? localOpen;\n const root = useRef<HTMLDivElement>(null);\n const previousOpen = useRef(false);\n const restoreFocus = useRef(true);\n const search = useRef({ value: \"\", time: 0 });\n // Bloom needs numeric closed geometry. A hidden HJM secondary Button with the same label measures it, so the\n // morph trigger and the canonical fallback trigger keep one size (2026-10-17 composition review).\n const measure = useRef<HTMLButtonElement>(null);\n const [buttonSize, setButtonSize] = useState({ width: 160, height: 44 });\n const motionPath = !(theme.environment.reducedMotion || theme.environment.direction === \"rtl\");\n useLayoutEffect(() => {\n const node = measure.current;\n if (!node) return;\n const read = () => setButtonSize(current => {\n const width = Math.ceil(node.offsetWidth), height = Math.ceil(node.offsetHeight);\n return width > 0 && height > 0 && (width !== current.width || height !== current.height) ? { width, height } : current;\n });\n read();\n if (typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(read);\n observer.observe(node);\n return () => observer.disconnect();\n }, [motionPath, label]);\n const change = (value: boolean) => { if (value) restoreFocus.current = true; setLocalOpen(value); onOpenChange?.(value); };\n if (!label.trim() || !items.length || new Set(items.map(item => item.id)).size !== items.length ||\n items.some(item => !item.id.trim() || !(item.textValue ?? (typeof item.label === \"string\" ? item.label : \"\")).trim())) {\n throw new TypeError(\"MorphingMenu needs a label and unique, named items\");\n }\n useEffect(() => {\n const host = root.current;\n if (open) {\n search.current = { value: \"\", time: 0 };\n host?.querySelector('[role=\"menu\"]')?.setAttribute(\"aria-label\", label);\n host?.querySelector<HTMLElement>('[role=\"menuitem\"]:not([disabled])')?.focus();\n } else if (previousOpen.current && restoreFocus.current && (host?.contains(document.activeElement) || document.activeElement === document.body)) host?.querySelector<HTMLElement>('[role=\"button\"]')?.focus();\n previousOpen.current = open;\n }, [open, label]);\n // The canonical Menu owns static/RTL behavior; Bloom's left/right geometry is physical.\n const chevron = <Icon name=\"chevronDown\" />;\n if (!motionPath) {\n return <Menu label={label} trigger={<Button tone=\"secondary\" trailing={chevron}>{label}</Button>} items={items} disabled={disabled} open={open}\n {...(layoutStyle === undefined ? {} : { layoutStyle })} onOpenChange={change} {...(onAction ? { onAction } : {})} />;\n }\n const keyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (!open) {\n if (!disabled && [\"ArrowDown\", \"ArrowUp\"].includes(event.key)) { event.preventDefault(); event.stopPropagation(); change(true); }\n return;\n }\n const nodes = Array.from(root.current?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]:not([disabled])') ?? []);\n const index = nodes.indexOf(document.activeElement as HTMLElement);\n let next: number | undefined;\n if (event.key === \"ArrowDown\") next = (index + 1) % nodes.length;\n if (event.key === \"ArrowUp\") next = (index - 1 + nodes.length) % nodes.length;\n if (event.key === \"Home\") next = 0;\n if (event.key === \"End\") next = nodes.length - 1;\n if (event.key === \"Escape\" || event.key === \"Tab\") { if (event.key === \"Tab\") restoreFocus.current = false; change(false); if (event.key === \"Escape\") event.preventDefault(); }\n if (event.key.length === 1 && !event.altKey && !event.ctrlKey && !event.metaKey && event.key !== \" \") {\n const result = resolveMenuTypeahead(\n items.filter(item => !item.disabled).map(item => ({\n textValue: item.textValue ?? (typeof item.label === \"string\" ? item.label : \"\"),\n })), index, event.key, search.current, Date.now(),\n );\n search.current = result.state;\n next = result.index;\n }\n if (next !== undefined && next >= 0) { event.preventDefault(); event.stopPropagation(); nodes[next]?.focus(); }\n };\n return <div ref={root} className=\"hjm-menu-morph\" data-open={open} style={layoutStyle} onKeyDownCapture={keyDown}>\n <Button ref={measure} tone=\"secondary\" trailing={chevron} className=\"hjm-menu-morph__measure\" aria-hidden=\"true\" tabIndex={-1} inert>{label}</Button>\n {/* Open toward following content; upstream defaults upward and can cover preceding values. */}\n <Bloom.Root direction=\"bottom\" open={open} onOpenChange={change} modal={false}>\n <Bloom.Container buttonSize={buttonSize} buttonRadius={radius.md} menuWidth={240} className=\"hjm-menu-morph__surface\">\n <Bloom.Trigger disabled={disabled} className=\"hjm-menu-morph__trigger\"><span className=\"hjm-button__label\">{label}</span>{chevron}</Bloom.Trigger>\n <Bloom.Content>\n {items.map(item => <button type=\"button\" role=\"menuitem\" tabIndex={-1} className=\"hjm-menu-morph__item\" key={item.id} disabled={!open || disabled || (item.disabled ?? false)}\n data-tone={item.tone} aria-label={item.textValue}\n onClick={() => { if (!disabled && !item.disabled) { change(false); onAction?.(item.id); } }}>\n {item.leading}{item.label}{item.trailing}\n </button>)}\n </Bloom.Content>\n </Bloom.Container>\n </Bloom.Root>\n </div>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"menu-morph.js","sourceRoot":"","sources":["../src/menu-morph.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\nimport { resolveMenuTypeahead } from \"./menu-typeahead.js\";\nimport { Menu as Bloom } from \"bloom-menu\";\nimport { useEffect, useLayoutEffect, useRef, useState, type KeyboardEvent } from \"react\";\nimport { radius } from \"@hjmds/design-contracts/foundations\";\nimport { Button } from \"./actions.js\";\nimport { Icon } from \"./supplemental-display.js\";\nimport { Menu, type MenuItem } from \"./overlays.js\";\nimport { useHjmTheme } from \"./provider.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type MorphingMenuProps = {\n label: string;\n items: readonly MenuItem[];\n onAction?: (id: string) => void;\n disabled?: boolean;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n /**\n * Canonical layout-only placement. Applied to the morph root, or to the\n * canonical Menu's wrapper when reduced motion/RTL falls back to it, so\n * placement survives the switch.\n */\n layoutStyle?: HjmCompositionStyleProp;\n};\n\n/** Action-only morph presentation. Selection/async menus retain the full Menu. */\nexport function MorphingMenu({ label, items, onAction, disabled = false, open: controlled, onOpenChange, layoutStyle }: MorphingMenuProps) {\n const theme = useHjmTheme();\n const [localOpen, setLocalOpen] = useState(false);\n const open = controlled ?? localOpen;\n const root = useRef<HTMLDivElement>(null);\n const previousOpen = useRef(false);\n const restoreFocus = useRef(true);\n const search = useRef({ value: \"\", time: 0 });\n // Bloom needs numeric closed geometry. A hidden HJM secondary Button with the same label measures it, so the\n // morph trigger and the canonical fallback trigger keep one size (2026-10-17 composition review).\n const measure = useRef<HTMLButtonElement>(null);\n const [buttonSize, setButtonSize] = useState({ width: 160, height: 44 });\n const motionPath = !(theme.environment.reducedMotion || theme.environment.direction === \"rtl\");\n useLayoutEffect(() => {\n const node = measure.current;\n if (!node) return;\n const read = () => setButtonSize(current => {\n const width = Math.ceil(node.offsetWidth), height = Math.ceil(node.offsetHeight);\n return width > 0 && height > 0 && (width !== current.width || height !== current.height) ? { width, height } : current;\n });\n read();\n if (typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(read);\n observer.observe(node);\n return () => observer.disconnect();\n }, [motionPath, label]);\n const change = (value: boolean) => { if (value) restoreFocus.current = true; setLocalOpen(value); onOpenChange?.(value); };\n if (!label.trim() || !items.length || new Set(items.map(item => item.id)).size !== items.length ||\n items.some(item => !item.id.trim() || !(item.textValue ?? (typeof item.label === \"string\" ? item.label : \"\")).trim())) {\n throw new TypeError(\"MorphingMenu needs a label and unique, named items\");\n }\n useEffect(() => {\n const host = root.current;\n if (open) {\n search.current = { value: \"\", time: 0 };\n host?.querySelector('[role=\"menu\"]')?.setAttribute(\"aria-label\", label);\n host?.querySelector<HTMLElement>('[role=\"menuitem\"]:not([disabled])')?.focus();\n } else if (previousOpen.current && restoreFocus.current && (host?.contains(document.activeElement) || document.activeElement === document.body)) host?.querySelector<HTMLElement>('[role=\"button\"]')?.focus();\n previousOpen.current = open;\n }, [open, label]);\n // The canonical Menu owns static/RTL behavior; Bloom's left/right geometry is physical.\n const chevron = <Icon name=\"chevronDown\" />;\n if (!motionPath) {\n return <Menu label={label} trigger={<Button tone=\"secondary\" trailing={chevron}>{label}</Button>} items={items} disabled={disabled} open={open}\n {...(layoutStyle === undefined ? {} : { layoutStyle })} onOpenChange={change} {...(onAction ? { onAction } : {})} />;\n }\n const keyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (!open) {\n if (!disabled && [\"ArrowDown\", \"ArrowUp\"].includes(event.key)) { event.preventDefault(); event.stopPropagation(); change(true); }\n return;\n }\n const nodes = Array.from(root.current?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]:not([disabled])') ?? []);\n const index = nodes.indexOf(document.activeElement as HTMLElement);\n let next: number | undefined;\n if (event.key === \"ArrowDown\") next = (index + 1) % nodes.length;\n if (event.key === \"ArrowUp\") next = (index - 1 + nodes.length) % nodes.length;\n if (event.key === \"Home\") next = 0;\n if (event.key === \"End\") next = nodes.length - 1;\n if (event.key === \"Escape\" || event.key === \"Tab\") { if (event.key === \"Tab\") restoreFocus.current = false; change(false); if (event.key === \"Escape\") event.preventDefault(); }\n if (event.key.length === 1 && !event.altKey && !event.ctrlKey && !event.metaKey && event.key !== \" \") {\n const result = resolveMenuTypeahead(\n items.filter(item => !item.disabled).map(item => ({\n textValue: item.textValue ?? (typeof item.label === \"string\" ? item.label : \"\"),\n })), index, event.key, search.current, Date.now(),\n );\n search.current = result.state;\n next = result.index;\n }\n if (next !== undefined && next >= 0) { event.preventDefault(); event.stopPropagation(); nodes[next]?.focus(); }\n };\n return <div ref={root} className=\"hjm-menu-morph\" data-open={open} style={layoutStyle} onKeyDownCapture={keyDown}>\n <Button ref={measure} tone=\"secondary\" trailing={chevron} className=\"hjm-menu-morph__measure\" aria-hidden=\"true\" tabIndex={-1} inert>{label}</Button>\n {/* Open toward following content; upstream defaults upward and can cover preceding values. */}\n <Bloom.Root direction=\"bottom\" open={open} onOpenChange={change} modal={false}>\n <Bloom.Container buttonSize={buttonSize} buttonRadius={radius.md} menuWidth={240} className=\"hjm-menu-morph__surface\">\n <Bloom.Trigger disabled={disabled} className=\"hjm-menu-morph__trigger\"><span className=\"hjm-button__label\">{label}</span>{chevron}</Bloom.Trigger>\n <Bloom.Content>\n {items.map(item => <button type=\"button\" role=\"menuitem\" tabIndex={-1} className=\"hjm-menu-morph__item\" key={item.id} disabled={!open || disabled || (item.disabled ?? false)}\n data-tone={item.tone} aria-label={item.textValue}\n onClick={() => { if (!disabled && !item.disabled) { change(false); onAction?.(item.id); } }}>\n {item.leading}{item.label}{item.trailing}\n </button>)}\n </Bloom.Content>\n </Bloom.Container>\n </Bloom.Root>\n </div>;\n}\n"]}
|
package/dist/menubar.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menubar.d.ts","sourceRoot":"","sources":["../src/menubar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"menubar.d.ts","sourceRoot":"","sources":["../src/menubar.tsx"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,4CAA4C,CAAC;AAIpD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,YAAY,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM,EAAE,OAAO,SAAS,MAAM,GAAG,MAAM,IAAI,QAAQ,CAAC;IAChG,UAAU,EAAE,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC5C,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5B,iBAAiB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;IAClD,QAAQ,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,wBAAgB,OAAO,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM,EAAE,OAAO,SAAS,MAAM,GAAG,MAAM,EAAE,EACpF,UAAU,EACV,UAAU,EAAE,cAAc,EAC1B,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,WAAW,GACZ,EAAE,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,+BAiM5B"}
|
package/dist/menubar.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
3
|
import { layer } from "@hjmds/design-contracts/foundations";
|
|
3
4
|
import { menubarRecipe, resolveMenubarNavigation, validateMenubarDescriptor, } from "@hjmds/design-contracts/components/menubar";
|
package/dist/menubar.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menubar.js","sourceRoot":"","sources":["../src/menubar.tsx"],"names":[],"mappings":"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","sourcesContent":["import { layer } from \"@hjmds/design-contracts/foundations\";\nimport {\n menubarRecipe,\n resolveMenubarNavigation,\n validateMenubarDescriptor,\n type MenubarDescriptor,\n} from \"@hjmds/design-contracts/components/menubar\";\nimport { useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, type CSSProperties, type RefObject } from \"react\";\nimport { classNames, useControllableState } from \"./internal.js\";\nimport { AnchoredPortal, useAnchoredPopup } from \"./portal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type MenubarProps<Key extends string = string, MenuKey extends string = string> = Readonly<{\n descriptor: MenubarDescriptor<Key, MenuKey>;\n openMenuId?: MenuKey | null;\n defaultOpenMenuId?: MenuKey | null;\n onOpenMenuIdChange?: (id: MenuKey | null) => void;\n onAction: (id: Key, menuId: MenuKey) => void;\n className?: string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport function Menubar<Key extends string = string, MenuKey extends string = string>({\n descriptor,\n openMenuId: controlledOpen,\n defaultOpenMenuId,\n onOpenMenuIdChange,\n onAction,\n className,\n layoutStyle,\n}: MenubarProps<Key, MenuKey>) {\n validateMenubarDescriptor(descriptor);\n const [openId, setOpenId] = useControllableState<MenuKey | null>({\n ...(controlledOpen === undefined ? {} : { value: controlledOpen }),\n defaultValue: defaultOpenMenuId ?? null,\n ...(onOpenMenuIdChange === undefined ? {} : { onChange: onOpenMenuIdChange }),\n });\n const enabledMenus = descriptor.menus.filter((menu) => menu.disabled !== true);\n // Roving focus: the bar is one tab stop, so the bar — not each label — owns\n // which menu is reachable by Tab.\n const [focusedId, setFocusedId] = useState<MenuKey>(enabledMenus[0]?.id ?? descriptor.menus[0]!.id);\n const [activeItemIndex, setActiveItemIndex] = useState(0);\n const rootRef = useRef<HTMLDivElement>(null);\n const labelRefs = useRef(new Map<MenuKey, HTMLButtonElement>());\n const focusedNode = useRef<HTMLButtonElement | null>(null);\n const previousMenuIds = useRef(descriptor.menus.map(menu => menu.id));\n const fallbackIndex = Math.min(Math.max(0, previousMenuIds.current.indexOf(focusedId)), Math.max(0, enabledMenus.length - 1));\n const resolvedFocusedId = enabledMenus.some(menu => menu.id === focusedId) ? focusedId : enabledMenus[fallbackIndex]?.id;\n const openMenu = descriptor.menus.find((menu) => menu.id === openId && !menu.disabled) ?? null;\n const effectiveOpenId = openMenu?.id ?? null;\n const openItems = openMenu?.items.filter((item) => item.disabled !== true) ?? [];\n const resolvedItemIndex = Math.min(activeItemIndex, Math.max(0, openItems.length - 1));\n useLayoutEffect(() => {\n previousMenuIds.current = descriptor.menus.map(menu => menu.id);\n if (resolvedFocusedId !== focusedId) {\n if (resolvedFocusedId !== undefined) setFocusedId(resolvedFocusedId);\n // Removing/disabling the focused label must leave a usable keyboard origin.\n if (focusedNode.current && (document.activeElement === document.body || document.activeElement === focusedNode.current)) {\n (resolvedFocusedId === undefined ? rootRef.current : labelRefs.current.get(resolvedFocusedId))?.focus();\n }\n }\n if (openId !== null && effectiveOpenId === null) setOpenId(null);\n if (resolvedItemIndex !== activeItemIndex) setActiveItemIndex(resolvedItemIndex);\n }, [descriptor.menus, resolvedFocusedId, focusedId, openId, effectiveOpenId, setOpenId, resolvedItemIndex, activeItemIndex]);\n // The panel was absolute inside the bar, so any overflow ancestor clipped it\n // (2026-09-30 audit WR-0930-4: at 1100px an item could not be hit). It now uses\n // the same portal + fixed positioning as Menu; focus stays on the bar label.\n const panelId = `${useId().replaceAll(\":\", \"\")}-menubar-panel`;\n const [panelNode, setPanelNode] = useState<HTMLDivElement | null>(null);\n const setPanelRef = useCallback((node: HTMLDivElement | null) => setPanelNode(node), []);\n const openLabelRef = useMemo<RefObject<HTMLElement | null>>(\n () => ({ get current() { return openId === null ? null : labelRefs.current.get(openId) ?? null; } }),\n [openId],\n );\n const panelPosition = useAnchoredPopup(openLabelRef, panelNode, { gap: 0, zIndex: layer.dropdown });\n\n useEffect(() => {\n if (openId === null) return;\n const onPointerDown = (event: PointerEvent) => {\n if (event.target instanceof Node && (rootRef.current?.contains(event.target) || panelNode?.contains(event.target))) return;\n setOpenId(null);\n };\n document.addEventListener(\"pointerdown\", onPointerDown);\n return () => document.removeEventListener(\"pointerdown\", onPointerDown);\n }, [openId, panelNode, setOpenId]);\n\n const focusLabel = (id: MenuKey) => {\n setFocusedId(id);\n labelRefs.current.get(id)?.focus();\n };\n const move = (direction: \"next\" | \"previous\") => {\n const next = resolveMenubarNavigation(descriptor, resolvedFocusedId ?? focusedId, direction);\n focusLabel(next);\n // Left/right while a menu is open moves to the neighbour already open, which\n // is the whole reason this is a bar and not three independent Menus.\n if (effectiveOpenId !== null) { setOpenId(next); setActiveItemIndex(0); }\n };\n\n return (\n <div\n ref={rootRef}\n role=\"menubar\"\n tabIndex={enabledMenus.length === 0 ? 0 : undefined}\n aria-label={descriptor.accessibilityLabel}\n className={classNames(\"hjm-menubar\", className)}\n style={{ ...layoutStyle,\n \"--hjm-menubar-min-height\": `${menubarRecipe.minHeight}px`,\n \"--hjm-menubar-gap\": `${menubarRecipe.gap}px`,\n \"--hjm-menubar-padding\": `${menubarRecipe.paddingHorizontal}px`,\n \"--hjm-menubar-label-padding\": `${menubarRecipe.label.paddingHorizontal}px`,\n // Consume the label sm role through CSS inheritance, retaining standalone recipe geometry.\n \"--hjm-menubar-label-radius\": `var(--hjm-radius-sm, ${menubarRecipe.label.radius}px)`,\n } as CSSProperties}\n onKeyDown={(event) => {\n if (resolvedFocusedId === undefined) return;\n const rtl = getComputedStyle(event.currentTarget).direction === \"rtl\";\n if (event.key === \"ArrowRight\") { event.preventDefault(); move(rtl ? \"previous\" : \"next\"); return; }\n if (event.key === \"ArrowLeft\") { event.preventDefault(); move(rtl ? \"next\" : \"previous\"); return; }\n if (event.key === \"Home\" || event.key === \"End\") {\n event.preventDefault();\n const target = (event.key === \"Home\" ? enabledMenus[0] : enabledMenus.at(-1))?.id;\n if (target !== undefined) { focusLabel(target); if (effectiveOpenId !== null) { setOpenId(target); setActiveItemIndex(0); } }\n return;\n }\n if (event.key === \"Escape\" && effectiveOpenId !== null) {\n event.preventDefault();\n setOpenId(null);\n focusLabel(resolvedFocusedId);\n return;\n }\n if (effectiveOpenId === null) {\n if (event.key === \"ArrowDown\" || event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n setOpenId(resolvedFocusedId);\n setActiveItemIndex(0);\n }\n return;\n }\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n setActiveItemIndex((previous) => {\n const next = event.key === \"ArrowDown\" ? previous + 1 : previous - 1;\n return (next + openItems.length) % Math.max(openItems.length, 1);\n });\n return;\n }\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n const item = openItems[resolvedItemIndex];\n if (item) {\n onAction(item.id as Key, effectiveOpenId);\n // Activation runs an action and leaves nothing selected — unlike Tabs.\n setOpenId(null);\n focusLabel(effectiveOpenId);\n }\n }\n }}\n >\n {descriptor.menus.map((menu) => {\n const open = menu.id === effectiveOpenId;\n return (\n <div key={menu.id} className=\"hjm-menubar__menu\">\n <button\n type=\"button\"\n ref={(node) => { if (node) labelRefs.current.set(menu.id, node); else labelRefs.current.delete(menu.id); }}\n role=\"menuitem\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-controls={open ? panelId : undefined}\n disabled={menu.disabled}\n tabIndex={menu.id === resolvedFocusedId ? 0 : -1}\n onFocus={(event) => { focusedNode.current = event.currentTarget; setFocusedId(menu.id); }}\n data-open={open || undefined}\n className=\"hjm-menubar__label\"\n onClick={() => {\n setFocusedId(menu.id);\n setOpenId(open ? null : menu.id);\n setActiveItemIndex(0);\n }}\n onMouseEnter={() => {\n // Once one menu is open, hovering the bar switches menus — the\n // desktop convention; with nothing open, hover opens nothing.\n if (effectiveOpenId !== null && menu.disabled !== true) { setOpenId(menu.id); setFocusedId(menu.id); setActiveItemIndex(0); }\n }}\n >\n {menu.label}\n </button>\n {open ? (\n <AnchoredPortal anchorRef={openLabelRef} ssrFallback=\"inline\">\n <div ref={setPanelRef} id={panelId} role=\"menu\" aria-label={menu.label} className=\"hjm-menubar__panel\" data-placement={panelPosition.placement} style={panelPosition.style}>\n {menu.items.map((item) => {\n // Popup positioning can cause mouseenter under a stationary\n // cursor. Only movement should replace a keyboard choice.\n const index = openItems.findIndex((candidate) => candidate.id === item.id);\n return (\n <div\n key={item.id}\n role=\"menuitem\"\n aria-disabled={item.disabled || undefined}\n data-active={index === resolvedItemIndex && item.disabled !== true ? \"\" : undefined}\n data-tone={item.tone}\n className=\"hjm-menubar__item\"\n onMouseMove={() => { if (index >= 0) setActiveItemIndex(index); }}\n onClick={() => {\n if (item.disabled) return;\n onAction(item.id as Key, menu.id);\n setOpenId(null);\n focusLabel(menu.id);\n }}\n >\n <span>{item.label}</span>\n {item.shortcut ? <kbd className=\"hjm-menubar__shortcut\">{item.shortcut}</kbd> : null}\n </div>\n );\n })}\n </div>\n </AnchoredPortal>\n ) : null}\n </div>\n );\n })}\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"menubar.js","sourceRoot":"","sources":["../src/menubar.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\nimport { layer } from \"@hjmds/design-contracts/foundations\";\nimport {\n menubarRecipe,\n resolveMenubarNavigation,\n validateMenubarDescriptor,\n type MenubarDescriptor,\n} from \"@hjmds/design-contracts/components/menubar\";\nimport { useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, type CSSProperties, type RefObject } from \"react\";\nimport { classNames, useControllableState } from \"./internal.js\";\nimport { AnchoredPortal, useAnchoredPopup } from \"./portal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type MenubarProps<Key extends string = string, MenuKey extends string = string> = Readonly<{\n descriptor: MenubarDescriptor<Key, MenuKey>;\n openMenuId?: MenuKey | null;\n defaultOpenMenuId?: MenuKey | null;\n onOpenMenuIdChange?: (id: MenuKey | null) => void;\n onAction: (id: Key, menuId: MenuKey) => void;\n className?: string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport function Menubar<Key extends string = string, MenuKey extends string = string>({\n descriptor,\n openMenuId: controlledOpen,\n defaultOpenMenuId,\n onOpenMenuIdChange,\n onAction,\n className,\n layoutStyle,\n}: MenubarProps<Key, MenuKey>) {\n validateMenubarDescriptor(descriptor);\n const [openId, setOpenId] = useControllableState<MenuKey | null>({\n ...(controlledOpen === undefined ? {} : { value: controlledOpen }),\n defaultValue: defaultOpenMenuId ?? null,\n ...(onOpenMenuIdChange === undefined ? {} : { onChange: onOpenMenuIdChange }),\n });\n const enabledMenus = descriptor.menus.filter((menu) => menu.disabled !== true);\n // Roving focus: the bar is one tab stop, so the bar — not each label — owns\n // which menu is reachable by Tab.\n const [focusedId, setFocusedId] = useState<MenuKey>(enabledMenus[0]?.id ?? descriptor.menus[0]!.id);\n const [activeItemIndex, setActiveItemIndex] = useState(0);\n const rootRef = useRef<HTMLDivElement>(null);\n const labelRefs = useRef(new Map<MenuKey, HTMLButtonElement>());\n const focusedNode = useRef<HTMLButtonElement | null>(null);\n const previousMenuIds = useRef(descriptor.menus.map(menu => menu.id));\n const fallbackIndex = Math.min(Math.max(0, previousMenuIds.current.indexOf(focusedId)), Math.max(0, enabledMenus.length - 1));\n const resolvedFocusedId = enabledMenus.some(menu => menu.id === focusedId) ? focusedId : enabledMenus[fallbackIndex]?.id;\n const openMenu = descriptor.menus.find((menu) => menu.id === openId && !menu.disabled) ?? null;\n const effectiveOpenId = openMenu?.id ?? null;\n const openItems = openMenu?.items.filter((item) => item.disabled !== true) ?? [];\n const resolvedItemIndex = Math.min(activeItemIndex, Math.max(0, openItems.length - 1));\n useLayoutEffect(() => {\n previousMenuIds.current = descriptor.menus.map(menu => menu.id);\n if (resolvedFocusedId !== focusedId) {\n if (resolvedFocusedId !== undefined) setFocusedId(resolvedFocusedId);\n // Removing/disabling the focused label must leave a usable keyboard origin.\n if (focusedNode.current && (document.activeElement === document.body || document.activeElement === focusedNode.current)) {\n (resolvedFocusedId === undefined ? rootRef.current : labelRefs.current.get(resolvedFocusedId))?.focus();\n }\n }\n if (openId !== null && effectiveOpenId === null) setOpenId(null);\n if (resolvedItemIndex !== activeItemIndex) setActiveItemIndex(resolvedItemIndex);\n }, [descriptor.menus, resolvedFocusedId, focusedId, openId, effectiveOpenId, setOpenId, resolvedItemIndex, activeItemIndex]);\n // The panel was absolute inside the bar, so any overflow ancestor clipped it\n // (2026-09-30 audit WR-0930-4: at 1100px an item could not be hit). It now uses\n // the same portal + fixed positioning as Menu; focus stays on the bar label.\n const panelId = `${useId().replaceAll(\":\", \"\")}-menubar-panel`;\n const [panelNode, setPanelNode] = useState<HTMLDivElement | null>(null);\n const setPanelRef = useCallback((node: HTMLDivElement | null) => setPanelNode(node), []);\n const openLabelRef = useMemo<RefObject<HTMLElement | null>>(\n () => ({ get current() { return openId === null ? null : labelRefs.current.get(openId) ?? null; } }),\n [openId],\n );\n const panelPosition = useAnchoredPopup(openLabelRef, panelNode, { gap: 0, zIndex: layer.dropdown });\n\n useEffect(() => {\n if (openId === null) return;\n const onPointerDown = (event: PointerEvent) => {\n if (event.target instanceof Node && (rootRef.current?.contains(event.target) || panelNode?.contains(event.target))) return;\n setOpenId(null);\n };\n document.addEventListener(\"pointerdown\", onPointerDown);\n return () => document.removeEventListener(\"pointerdown\", onPointerDown);\n }, [openId, panelNode, setOpenId]);\n\n const focusLabel = (id: MenuKey) => {\n setFocusedId(id);\n labelRefs.current.get(id)?.focus();\n };\n const move = (direction: \"next\" | \"previous\") => {\n const next = resolveMenubarNavigation(descriptor, resolvedFocusedId ?? focusedId, direction);\n focusLabel(next);\n // Left/right while a menu is open moves to the neighbour already open, which\n // is the whole reason this is a bar and not three independent Menus.\n if (effectiveOpenId !== null) { setOpenId(next); setActiveItemIndex(0); }\n };\n\n return (\n <div\n ref={rootRef}\n role=\"menubar\"\n tabIndex={enabledMenus.length === 0 ? 0 : undefined}\n aria-label={descriptor.accessibilityLabel}\n className={classNames(\"hjm-menubar\", className)}\n style={{ ...layoutStyle,\n \"--hjm-menubar-min-height\": `${menubarRecipe.minHeight}px`,\n \"--hjm-menubar-gap\": `${menubarRecipe.gap}px`,\n \"--hjm-menubar-padding\": `${menubarRecipe.paddingHorizontal}px`,\n \"--hjm-menubar-label-padding\": `${menubarRecipe.label.paddingHorizontal}px`,\n // Consume the label sm role through CSS inheritance, retaining standalone recipe geometry.\n \"--hjm-menubar-label-radius\": `var(--hjm-radius-sm, ${menubarRecipe.label.radius}px)`,\n } as CSSProperties}\n onKeyDown={(event) => {\n if (resolvedFocusedId === undefined) return;\n const rtl = getComputedStyle(event.currentTarget).direction === \"rtl\";\n if (event.key === \"ArrowRight\") { event.preventDefault(); move(rtl ? \"previous\" : \"next\"); return; }\n if (event.key === \"ArrowLeft\") { event.preventDefault(); move(rtl ? \"next\" : \"previous\"); return; }\n if (event.key === \"Home\" || event.key === \"End\") {\n event.preventDefault();\n const target = (event.key === \"Home\" ? enabledMenus[0] : enabledMenus.at(-1))?.id;\n if (target !== undefined) { focusLabel(target); if (effectiveOpenId !== null) { setOpenId(target); setActiveItemIndex(0); } }\n return;\n }\n if (event.key === \"Escape\" && effectiveOpenId !== null) {\n event.preventDefault();\n setOpenId(null);\n focusLabel(resolvedFocusedId);\n return;\n }\n if (effectiveOpenId === null) {\n if (event.key === \"ArrowDown\" || event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n setOpenId(resolvedFocusedId);\n setActiveItemIndex(0);\n }\n return;\n }\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n setActiveItemIndex((previous) => {\n const next = event.key === \"ArrowDown\" ? previous + 1 : previous - 1;\n return (next + openItems.length) % Math.max(openItems.length, 1);\n });\n return;\n }\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n const item = openItems[resolvedItemIndex];\n if (item) {\n onAction(item.id as Key, effectiveOpenId);\n // Activation runs an action and leaves nothing selected — unlike Tabs.\n setOpenId(null);\n focusLabel(effectiveOpenId);\n }\n }\n }}\n >\n {descriptor.menus.map((menu) => {\n const open = menu.id === effectiveOpenId;\n return (\n <div key={menu.id} className=\"hjm-menubar__menu\">\n <button\n type=\"button\"\n ref={(node) => { if (node) labelRefs.current.set(menu.id, node); else labelRefs.current.delete(menu.id); }}\n role=\"menuitem\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-controls={open ? panelId : undefined}\n disabled={menu.disabled}\n tabIndex={menu.id === resolvedFocusedId ? 0 : -1}\n onFocus={(event) => { focusedNode.current = event.currentTarget; setFocusedId(menu.id); }}\n data-open={open || undefined}\n className=\"hjm-menubar__label\"\n onClick={() => {\n setFocusedId(menu.id);\n setOpenId(open ? null : menu.id);\n setActiveItemIndex(0);\n }}\n onMouseEnter={() => {\n // Once one menu is open, hovering the bar switches menus — the\n // desktop convention; with nothing open, hover opens nothing.\n if (effectiveOpenId !== null && menu.disabled !== true) { setOpenId(menu.id); setFocusedId(menu.id); setActiveItemIndex(0); }\n }}\n >\n {menu.label}\n </button>\n {open ? (\n <AnchoredPortal anchorRef={openLabelRef} ssrFallback=\"inline\">\n <div ref={setPanelRef} id={panelId} role=\"menu\" aria-label={menu.label} className=\"hjm-menubar__panel\" data-placement={panelPosition.placement} style={panelPosition.style}>\n {menu.items.map((item) => {\n // Popup positioning can cause mouseenter under a stationary\n // cursor. Only movement should replace a keyboard choice.\n const index = openItems.findIndex((candidate) => candidate.id === item.id);\n return (\n <div\n key={item.id}\n role=\"menuitem\"\n aria-disabled={item.disabled || undefined}\n data-active={index === resolvedItemIndex && item.disabled !== true ? \"\" : undefined}\n data-tone={item.tone}\n className=\"hjm-menubar__item\"\n onMouseMove={() => { if (index >= 0) setActiveItemIndex(index); }}\n onClick={() => {\n if (item.disabled) return;\n onAction(item.id as Key, menu.id);\n setOpenId(null);\n focusLabel(menu.id);\n }}\n >\n <span>{item.label}</span>\n {item.shortcut ? <kbd className=\"hjm-menubar__shortcut\">{item.shortcut}</kbd> : null}\n </div>\n );\n })}\n </div>\n </AnchoredPortal>\n ) : null}\n </div>\n );\n })}\n </div>\n );\n}\n"]}
|
package/dist/modal.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../src/modal.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../src/modal.tsx"],"names":[],"mappings":"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"}
|
package/dist/modal.js
CHANGED