@tribepad/themis 1.0.2 → 1.0.3
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/dist/elements/Checkbox/index.js +1 -1
- package/dist/elements/Checkbox/index.js.map +1 -1
- package/dist/elements/Checkbox/index.mjs +1 -1
- package/dist/elements/Checkbox/index.mjs.map +1 -1
- package/dist/elements/CheckboxGroup/index.js +1 -1
- package/dist/elements/CheckboxGroup/index.js.map +1 -1
- package/dist/elements/CheckboxGroup/index.mjs +1 -1
- package/dist/elements/CheckboxGroup/index.mjs.map +1 -1
- package/dist/elements/DatePicker/index.js +1 -1
- package/dist/elements/DatePicker/index.js.map +1 -1
- package/dist/elements/DatePicker/index.mjs +1 -1
- package/dist/elements/DatePicker/index.mjs.map +1 -1
- package/dist/elements/FileField/index.js +1 -1
- package/dist/elements/FileField/index.js.map +1 -1
- package/dist/elements/FileField/index.mjs +1 -1
- package/dist/elements/FileField/index.mjs.map +1 -1
- package/dist/elements/NumberField/NumberField.variants.d.ts +1 -1
- package/dist/elements/NumberField/index.js +1 -1
- package/dist/elements/NumberField/index.js.map +1 -1
- package/dist/elements/NumberField/index.mjs +1 -1
- package/dist/elements/NumberField/index.mjs.map +1 -1
- package/dist/elements/OTPInput/index.js +1 -1
- package/dist/elements/OTPInput/index.js.map +1 -1
- package/dist/elements/OTPInput/index.mjs +1 -1
- package/dist/elements/OTPInput/index.mjs.map +1 -1
- package/dist/elements/Progress/index.js +1 -1
- package/dist/elements/Progress/index.js.map +1 -1
- package/dist/elements/Progress/index.mjs +1 -1
- package/dist/elements/Progress/index.mjs.map +1 -1
- package/dist/elements/RadioGroup/index.js +1 -1
- package/dist/elements/RadioGroup/index.js.map +1 -1
- package/dist/elements/RadioGroup/index.mjs +1 -1
- package/dist/elements/RadioGroup/index.mjs.map +1 -1
- package/dist/elements/Resizable/index.js +1 -1
- package/dist/elements/Resizable/index.js.map +1 -1
- package/dist/elements/Resizable/index.mjs +1 -1
- package/dist/elements/Resizable/index.mjs.map +1 -1
- package/dist/elements/Select/index.js +1 -1
- package/dist/elements/Select/index.js.map +1 -1
- package/dist/elements/Select/index.mjs +1 -1
- package/dist/elements/Select/index.mjs.map +1 -1
- package/dist/elements/Switch/index.js +1 -1
- package/dist/elements/Switch/index.js.map +1 -1
- package/dist/elements/Switch/index.mjs +1 -1
- package/dist/elements/Switch/index.mjs.map +1 -1
- package/dist/elements/Table/index.js +1 -1
- package/dist/elements/Table/index.js.map +1 -1
- package/dist/elements/Table/index.mjs +1 -1
- package/dist/elements/Table/index.mjs.map +1 -1
- package/dist/elements/Tabs/Tabs.d.ts +5 -3
- package/dist/elements/Tabs/Tabs.d.ts.map +1 -1
- package/dist/elements/Tabs/Tabs.types.d.ts +15 -0
- package/dist/elements/Tabs/Tabs.types.d.ts.map +1 -1
- package/dist/elements/Tabs/index.js +1 -1
- package/dist/elements/Tabs/index.js.map +1 -1
- package/dist/elements/Tabs/index.mjs +1 -1
- package/dist/elements/Tabs/index.mjs.map +1 -1
- package/dist/elements/TimeField/index.js +1 -1
- package/dist/elements/TimeField/index.js.map +1 -1
- package/dist/elements/TimeField/index.mjs +1 -1
- package/dist/elements/TimeField/index.mjs.map +1 -1
- package/dist/elements/index.js +1 -1
- package/dist/elements/index.js.map +1 -1
- package/dist/elements/index.mjs +1 -1
- package/dist/elements/index.mjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/styles/index.js +1 -1
- package/dist/styles/index.js.map +1 -1
- package/dist/styles/index.mjs +1 -1
- package/dist/styles/index.mjs.map +1 -1
- package/dist/styles/shared-variants.d.ts +3 -3
- package/dist/styles/shared-variants.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/elements/AlertDialog/AlertDialog.stories.tsx +1 -1
- package/src/elements/CheckboxGroup/CheckboxGroup.stories.tsx +3 -3
- package/src/elements/Combobox/Combobox.stories.tsx +1 -1
- package/src/elements/FileField/FileField.stories.tsx +1 -1
- package/src/elements/Progress/Progress.stories.tsx +6 -1
- package/src/elements/RadioGroup/RadioGroup.stories.tsx +2 -2
- package/src/elements/Tabs/Tabs.stories.tsx +45 -1
package/dist/styles/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var e="data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2",a="data-[pressed]:scale-[0.97]",E="data-[pressed]:transition-transform data-[pressed]:duration-100",r="data-[hovered]:shadow-md",
|
|
1
|
+
'use strict';var e="data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2",a="data-[pressed]:scale-[0.97]",E="data-[pressed]:transition-transform data-[pressed]:duration-100",r="data-[hovered]:shadow-md",c="data-[hovered]:transition-shadow data-[hovered]:duration-200",t="hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground",n="hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground",s="hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground",i=`${t} ${n} ${s}`,_="disabled:pointer-events-none disabled:opacity-50",T=`${e} ${a} ${r} ${t} ${n} ${s}`,I=`${e} ${t}`,d="cursor-default select-none";var A=["focus-within:outline-none","focus-within:ring-2","focus-within:ring-[var(--ring)]","focus-within:ring-offset-2"],O=["focus-visible:outline-none","focus-visible:ring-2","focus-visible:ring-[var(--ring)]","focus-visible:ring-offset-2"],R=["focus:outline-none","focus:ring-2","focus:ring-[var(--ring)]"],u=["focus:outline-none","focus:bg-[var(--accent)]","focus:text-[var(--accent-foreground)]"],N=["disabled:pointer-events-none","disabled:opacity-50"],x=["data-[disabled]:pointer-events-none","data-[disabled]:opacity-50","data-[disabled]:cursor-not-allowed"],l={sm:"text-xs",default:"text-sm",lg:"text-base"},p={sm:"text-sm",default:"text-base",lg:"text-lg"},f=["min-h-[44px]","min-w-[44px]"],C={sm:"h-9 w-9",default:"h-11 w-11",lg:"h-14 w-14"},g={sm:"h-9",default:"h-11",lg:"h-14"},L=["flex","items-center","gap-1.5","text-[var(--destructive-background)]"],D=["flex","items-center","gap-1.5","text-[var(--success-background)]"],H=["text-[var(--menu-muted)]"],v=["font-medium","text-[var(--content-foreground)]"],h="after:content-['*'] after:ml-0.5 after:text-[var(--destructive-background)]",m=["data-[entering]:animate-in","data-[entering]:fade-in-0","data-[entering]:zoom-in-95"],U=["data-[exiting]:animate-out","data-[exiting]:fade-out-0","data-[exiting]:zoom-out-95"],b=["motion-reduce:transition-none","motion-reduce:animate-none"],G=["transition-colors","duration-200"],B=["transition-colors","duration-150"],M=["hover:bg-[var(--accent)]","hover:text-[var(--accent-foreground)]"];function F(...S){return S.flatMap(o=>Array.isArray(o)?[...o]:[o])}exports.DEFAULT_INTERACTIONS=T;exports.DESCRIPTION_BASE=H;exports.DISABLED_DATA_ATTR=x;exports.DISABLED_STANDARD=N;exports.DISABLED_STYLES=_;exports.ERROR_MESSAGE_BASE=L;exports.FIELD_HEIGHTS=g;exports.FOCUS_HIGHLIGHT=u;exports.FOCUS_RING=R;exports.FOCUS_STYLES=e;exports.FOCUS_VISIBLE_RING=O;exports.FOCUS_WITHIN_RING=A;exports.HIGH_CONTRAST_FOCUS=t;exports.HIGH_CONTRAST_HOVER=n;exports.HIGH_CONTRAST_INTERACTIONS=i;exports.HIGH_CONTRAST_PRESSED=s;exports.HOVER_ACCENT=M;exports.HOVER_STYLES=r;exports.HOVER_STYLES_BASE=c;exports.INTERACTIVE_SIZES=C;exports.LABEL_BASE=v;exports.NON_INTERACTIVE=d;exports.POPOVER_ANIMATION_IN=m;exports.POPOVER_ANIMATION_OUT=U;exports.PRESSED_STYLES=a;exports.PRESSED_STYLES_BASE=E;exports.REDUCED_MOTION=b;exports.REQUIRED_INDICATOR=h;exports.SUBTLE_INTERACTIONS=I;exports.SUCCESS_MESSAGE_BASE=D;exports.TEXT_SIZE_MEDIUM_SCALE=p;exports.TEXT_SIZE_SMALL_SCALE=l;exports.TOUCH_TARGET_MIN=f;exports.TRANSITION_COLORS=G;exports.TRANSITION_FAST=B;exports.combineStyles=F;//# sourceMappingURL=index.js.map
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/styles/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/styles/interaction-states.ts","../../src/styles/shared-variants.ts"],"names":["FOCUS_STYLES","PRESSED_STYLES","PRESSED_STYLES_BASE","HOVER_STYLES","HOVER_STYLES_BASE","HIGH_CONTRAST_FOCUS","HIGH_CONTRAST_HOVER","HIGH_CONTRAST_PRESSED","HIGH_CONTRAST_INTERACTIONS","DISABLED_STYLES","DEFAULT_INTERACTIONS","SUBTLE_INTERACTIONS","NON_INTERACTIVE","FOCUS_WITHIN_RING","FOCUS_VISIBLE_RING","FOCUS_RING","FOCUS_HIGHLIGHT","DISABLED_STANDARD","DISABLED_DATA_ATTR","TEXT_SIZE_SMALL_SCALE","TEXT_SIZE_MEDIUM_SCALE","TOUCH_TARGET_MIN","INTERACTIVE_SIZES","FIELD_HEIGHTS","ERROR_MESSAGE_BASE","SUCCESS_MESSAGE_BASE","DESCRIPTION_BASE","LABEL_BASE","REQUIRED_INDICATOR","POPOVER_ANIMATION_IN","POPOVER_ANIMATION_OUT","REDUCED_MOTION","TRANSITION_COLORS","TRANSITION_FAST","HOVER_ACCENT","combineStyles","styles","s"],"mappings":"aAoBO,IAAMA,CAAAA,CAAe,gHAUfC,CAAAA,CAAiB,6BAAA,CAKjBC,EAAsB,iEAAA,CAUtBC,CAAAA,CAAe,2BAKfC,CAAAA,CAAoB,8DAAA,CAQpBC,EAAsB,uJAAA,CAMtBC,CAAAA,CAAsB,6FAMtBC,CAAAA,CAAwB,+HAAA,CAMxBC,EAA6B,CAAA,EAAGH,CAAmB,CAAA,CAAA,EAAIC,CAAmB,CAAA,CAAA,EAAIC,CAAqB,GAMnGE,CAAAA,CAAkB,kDAAA,CAWlBC,EAAuB,CAAA,EAAGV,CAAY,IAAIC,CAAc,CAAA,CAAA,EAAIE,CAAY,CAAA,CAAA,EAAIE,CAAmB,CAAA,CAAA,EAAIC,CAAmB,CAAA,CAAA,EAAIC,CAAqB,GAQ/II,CAAAA,CAAsB,CAAA,EAAGX,CAAY,CAAA,CAAA,EAAIK,CAAmB,CAAA,CAAA,CAM5DO,CAAAA,CAAkB,6BC1FxB,IAAMC,EAAoB,CAC/B,2BAAA,CACA,sBACA,iCAAA,CACA,4BACF,EAMaC,CAAAA,CAAqB,CAChC,4BAAA,CACA,sBAAA,CACA,kCAAA,CACA,6BACF,EAMaC,CAAAA,CAAa,CACxB,qBACA,cAAA,CACA,0BACF,EAKaC,CAAAA,CAAkB,CAC7B,oBAAA,CACA,0BAAA,CACA,uCACF,CAAA,CASaC,EAAoB,CAC/B,8BAAA,CACA,qBACF,CAAA,CAKaC,CAAAA,CAAqB,CAChC,qCAAA,CACA,4BAAA,CACA,oCACF,CAAA,CASaC,CAAAA,CAAwB,CACnC,GAAI,SAAA,CACJ,OAAA,CAAS,UACT,EAAA,CAAI,WACN,EAKaC,CAAAA,CAAyB,CACpC,EAAA,CAAI,SAAA,CACJ,OAAA,CAAS,WAAA,CACT,GAAI,SACN,CAAA,CASaC,EAAmB,CAC9B,cAAA,CACA,cACF,CAAA,CAKaC,CAAAA,CAAoB,CAC/B,EAAA,CAAI,SAAA,CACJ,OAAA,CAAS,YACT,EAAA,CAAI,WACN,EAKaC,CAAAA,CAAgB,CAC3B,GAAI,KAAA,CACJ,OAAA,CAAS,MAAA,CACT,EAAA,CAAI,MACN,CAAA,CASaC,EAAqB,CAChC,MAAA,CACA,eACA,SAAA,CACA,2BACF,EAKaC,CAAAA,CAAuB,CAClC,MAAA,CACA,cAAA,CACA,SAAA,CACA,uBACF,EAKaC,CAAAA,CAAmB,CAC9B,0BACF,CAAA,CAKaC,CAAAA,CAAa,CACxB,aAAA,CACA,kCACF,CAAA,CAKaC,CAAAA,CAAqB,kEAAA,CASrBC,CAAAA,CAAuB,CAClC,4BAAA,CACA,2BAAA,CACA,4BACF,CAAA,CAKaC,CAAAA,CAAwB,CACnC,4BAAA,CACA,2BAAA,CACA,4BACF,CAAA,CAKaC,CAAAA,CAAiB,CAC5B,gCACA,4BACF,CAAA,CAKaC,EAAoB,CAC/B,mBAAA,CACA,cACF,CAAA,CAKaC,CAAAA,CAAkB,CAC7B,mBAAA,CACA,cACF,CAAA,CASaC,EAAe,CAC1B,0BAAA,CACA,uCACF,EASO,SAASC,KAAiBC,CAAAA,CAAkD,CACjF,OAAOA,CAAAA,CAAO,OAAA,CAAQC,CAAAA,EAAK,MAAM,OAAA,CAAQA,CAAC,EAAI,CAAC,GAAGA,CAAC,CAAA,CAAI,CAACA,CAAC,CAAC,CAC5D","file":"index.js","sourcesContent":["/**\n * Global Interaction State Styles\n *\n * Consistent interaction patterns across all Themis components.\n * These styles ensure WCAG 2.2 AAA compliance and predictable UX.\n *\n * @see spec.md FR-010 (Visible focus ring for keyboard navigation)\n * @see spec.md FR-031 (Pressed state feedback)\n * @see spec.md FR-012 (High contrast mode support)\n * @see constitution.md Principle IV (Accessibility First)\n */\n\n/**\n * Focus state styles (FR-010)\n * Visible focus ring for keyboard navigation - WCAG 2.2 Level AAA\n *\n * Components can override by extending these styles:\n * @example\n * cn(FOCUS_STYLES, \"ring-4\") // Increases ring width to 4px\n */\nexport const FOCUS_STYLES = \"data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2\";\n\n/**\n * Pressed/Active state styles (FR-031)\n * Visual feedback for press interactions\n *\n * Components can override the scale amount:\n * @example\n * cn(PRESSED_STYLES_BASE, \"data-[pressed]:scale-[0.95]\") // More pronounced scale\n */\nexport const PRESSED_STYLES = \"data-[pressed]:scale-[0.97]\";\n\n/**\n * Base pressed styles without scale (for components that need different feedback)\n */\nexport const PRESSED_STYLES_BASE = \"data-[pressed]:transition-transform data-[pressed]:duration-100\";\n\n/**\n * Hover state styles\n * Elevation change on hover for better affordance\n *\n * Components can override shadow depth:\n * @example\n * cn(HOVER_STYLES_BASE, \"data-[hovered]:shadow-lg\") // Larger shadow\n */\nexport const HOVER_STYLES = \"data-[hovered]:shadow-md\";\n\n/**\n * Base hover styles without shadow (for components that use different hover effects)\n */\nexport const HOVER_STYLES_BASE = \"data-[hovered]:transition-shadow data-[hovered]:duration-200\";\n\n/**\n * High contrast mode focus (FR-012)\n * Enhanced outlines for users requiring high contrast\n *\n * Uses 'hc:' prefix for prefers-contrast: more media query\n */\nexport const HIGH_CONTRAST_FOCUS = \"hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground\";\n\n/**\n * High contrast mode hover (FR-012)\n * Enhanced outlines for hover in high contrast mode\n */\nexport const HIGH_CONTRAST_HOVER = \"hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground\";\n\n/**\n * High contrast mode pressed state\n * Enhanced outlines for pressed state in high contrast mode\n */\nexport const HIGH_CONTRAST_PRESSED = \"hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground\";\n\n/**\n * Combined high contrast styles\n * Use this for components that need all high contrast interaction states\n */\nexport const HIGH_CONTRAST_INTERACTIONS = `${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Disabled state styles\n * Consistent disabled appearance across all components\n */\nexport const DISABLED_STYLES = \"disabled:pointer-events-none disabled:opacity-50\";\n\n/**\n * Default interaction bundle\n * Most common combination for interactive components\n *\n * Includes: focus ring, pressed scale, hover shadow, high contrast enhancements\n *\n * @example\n * <button className={cn(DEFAULT_INTERACTIONS, \"bg-primary\")}>Click</button>\n */\nexport const DEFAULT_INTERACTIONS = `${FOCUS_STYLES} ${PRESSED_STYLES} ${HOVER_STYLES} ${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Subtle interaction bundle\n * For components that need less pronounced feedback\n *\n * Includes: focus ring and high contrast, but no hover shadow or pressed scale\n */\nexport const SUBTLE_INTERACTIONS = `${FOCUS_STYLES} ${HIGH_CONTRAST_FOCUS}`;\n\n/**\n * Non-interactive element styles\n * For elements that should indicate they are not interactive\n */\nexport const NON_INTERACTIVE = \"cursor-default select-none\";\n","/**\n * Shared CVA Variant Utilities\n *\n * Common patterns extracted from component variants for consistency and reduced bundle size.\n * Use these constants in CVA definitions to ensure consistent styling across Themis.\n *\n * @see interaction-states.ts for interaction-specific styles (focus, hover, pressed)\n */\n\n// =============================================================================\n// Focus Ring Patterns\n// =============================================================================\n\n/**\n * Focus-within ring (for container elements with focusable children)\n * Use when the container should show focus when any child is focused\n */\nexport const FOCUS_WITHIN_RING = [\n 'focus-within:outline-none',\n 'focus-within:ring-2',\n 'focus-within:ring-[var(--ring)]',\n 'focus-within:ring-offset-2',\n] as const;\n\n/**\n * Focus-visible ring (for directly focusable elements)\n * Use for buttons, inputs, and other interactive elements\n */\nexport const FOCUS_VISIBLE_RING = [\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-[var(--ring)]',\n 'focus-visible:ring-offset-2',\n] as const;\n\n/**\n * Standard focus ring (for elements using :focus pseudo-class)\n * Prefer focus-visible when possible for better UX\n */\nexport const FOCUS_RING = [\n 'focus:outline-none',\n 'focus:ring-2',\n 'focus:ring-[var(--ring)]',\n] as const;\n\n/**\n * Focus with background change (for segments, cells, menu items)\n */\nexport const FOCUS_HIGHLIGHT = [\n 'focus:outline-none',\n 'focus:bg-[var(--accent)]',\n 'focus:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Disabled State Patterns\n// =============================================================================\n\n/**\n * Standard disabled state using disabled attribute\n */\nexport const DISABLED_STANDARD = [\n 'disabled:pointer-events-none',\n 'disabled:opacity-50',\n] as const;\n\n/**\n * Disabled state using data attribute (React Aria pattern)\n */\nexport const DISABLED_DATA_ATTR = [\n 'data-[disabled]:pointer-events-none',\n 'data-[disabled]:opacity-50',\n 'data-[disabled]:cursor-not-allowed',\n] as const;\n\n// =============================================================================\n// Size-Based Text Variants\n// =============================================================================\n\n/**\n * Small text size scale (xs -> sm -> base)\n */\nexport const TEXT_SIZE_SMALL_SCALE = {\n sm: 'text-xs',\n default: 'text-sm',\n lg: 'text-base',\n} as const;\n\n/**\n * Medium text size scale (sm -> base -> lg)\n */\nexport const TEXT_SIZE_MEDIUM_SCALE = {\n sm: 'text-sm',\n default: 'text-base',\n lg: 'text-lg',\n} as const;\n\n// =============================================================================\n// Touch Target Utilities\n// =============================================================================\n\n/**\n * WCAG 2.2 AAA minimum touch target (44x44px)\n */\nexport const TOUCH_TARGET_MIN = [\n 'min-h-[44px]',\n 'min-w-[44px]',\n] as const;\n\n/**\n * Common button/cell sizes with touch target compliance\n */\nexport const INTERACTIVE_SIZES = {\n sm: 'h-9 w-9', // 36px - desktop only, NOT AAA compliant\n default: 'h-11 w-11', // 44px - AAA compliant\n lg: 'h-14 w-14', // 56px - AAA compliant, enhanced\n} as const;\n\n/**\n * Height-only sizes for fields and inputs\n */\nexport const FIELD_HEIGHTS = {\n sm: 'h-9', // 36px\n default: 'h-11', // 44px\n lg: 'h-14', // 56px\n} as const;\n\n// =============================================================================\n// Message/Feedback Patterns\n// =============================================================================\n\n/**\n * Error message styling\n */\nexport const ERROR_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--destructive)]',\n] as const;\n\n/**\n * Success message styling\n */\nexport const SUCCESS_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--success)]',\n] as const;\n\n/**\n * Description/helper text styling\n */\nexport const DESCRIPTION_BASE = [\n 'text-[var(--menu-muted)]',\n] as const;\n\n/**\n * Label base styling\n */\nexport const LABEL_BASE = [\n 'font-medium',\n 'text-[var(--content-foreground)]',\n] as const;\n\n/**\n * Required indicator pattern\n */\nexport const REQUIRED_INDICATOR = \"after:content-['*'] after:ml-0.5 after:text-[var(--destructive)]\";\n\n// =============================================================================\n// Animation Patterns\n// =============================================================================\n\n/**\n * Popover/dropdown entry animation\n */\nexport const POPOVER_ANIMATION_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:zoom-in-95',\n] as const;\n\n/**\n * Popover/dropdown exit animation\n */\nexport const POPOVER_ANIMATION_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:zoom-out-95',\n] as const;\n\n/**\n * Reduced motion support (WCAG 2.2)\n */\nexport const REDUCED_MOTION = [\n 'motion-reduce:transition-none',\n 'motion-reduce:animate-none',\n] as const;\n\n/**\n * Standard transition for colors\n */\nexport const TRANSITION_COLORS = [\n 'transition-colors',\n 'duration-200',\n] as const;\n\n/**\n * Fast transition for interactions\n */\nexport const TRANSITION_FAST = [\n 'transition-colors',\n 'duration-150',\n] as const;\n\n// =============================================================================\n// Hover State Patterns\n// =============================================================================\n\n/**\n * Accent background on hover (for interactive items)\n */\nexport const HOVER_ACCENT = [\n 'hover:bg-[var(--accent)]',\n 'hover:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Combines multiple style arrays into a flat array for CVA base styles\n */\nexport function combineStyles(...styles: (readonly string[] | string)[]): string[] {\n return styles.flatMap(s => Array.isArray(s) ? [...s] : [s]);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/styles/interaction-states.ts","../../src/styles/shared-variants.ts"],"names":["FOCUS_STYLES","PRESSED_STYLES","PRESSED_STYLES_BASE","HOVER_STYLES","HOVER_STYLES_BASE","HIGH_CONTRAST_FOCUS","HIGH_CONTRAST_HOVER","HIGH_CONTRAST_PRESSED","HIGH_CONTRAST_INTERACTIONS","DISABLED_STYLES","DEFAULT_INTERACTIONS","SUBTLE_INTERACTIONS","NON_INTERACTIVE","FOCUS_WITHIN_RING","FOCUS_VISIBLE_RING","FOCUS_RING","FOCUS_HIGHLIGHT","DISABLED_STANDARD","DISABLED_DATA_ATTR","TEXT_SIZE_SMALL_SCALE","TEXT_SIZE_MEDIUM_SCALE","TOUCH_TARGET_MIN","INTERACTIVE_SIZES","FIELD_HEIGHTS","ERROR_MESSAGE_BASE","SUCCESS_MESSAGE_BASE","DESCRIPTION_BASE","LABEL_BASE","REQUIRED_INDICATOR","POPOVER_ANIMATION_IN","POPOVER_ANIMATION_OUT","REDUCED_MOTION","TRANSITION_COLORS","TRANSITION_FAST","HOVER_ACCENT","combineStyles","styles","s"],"mappings":"aAoBO,IAAMA,CAAAA,CAAe,gHAUfC,CAAAA,CAAiB,6BAAA,CAKjBC,EAAsB,iEAAA,CAUtBC,CAAAA,CAAe,2BAKfC,CAAAA,CAAoB,8DAAA,CAQpBC,EAAsB,uJAAA,CAMtBC,CAAAA,CAAsB,6FAMtBC,CAAAA,CAAwB,+HAAA,CAMxBC,EAA6B,CAAA,EAAGH,CAAmB,CAAA,CAAA,EAAIC,CAAmB,CAAA,CAAA,EAAIC,CAAqB,GAMnGE,CAAAA,CAAkB,kDAAA,CAWlBC,EAAuB,CAAA,EAAGV,CAAY,IAAIC,CAAc,CAAA,CAAA,EAAIE,CAAY,CAAA,CAAA,EAAIE,CAAmB,CAAA,CAAA,EAAIC,CAAmB,CAAA,CAAA,EAAIC,CAAqB,GAQ/II,CAAAA,CAAsB,CAAA,EAAGX,CAAY,CAAA,CAAA,EAAIK,CAAmB,CAAA,CAAA,CAM5DO,CAAAA,CAAkB,6BC1FxB,IAAMC,EAAoB,CAC/B,2BAAA,CACA,sBACA,iCAAA,CACA,4BACF,EAMaC,CAAAA,CAAqB,CAChC,4BAAA,CACA,sBAAA,CACA,kCAAA,CACA,6BACF,EAMaC,CAAAA,CAAa,CACxB,qBACA,cAAA,CACA,0BACF,EAKaC,CAAAA,CAAkB,CAC7B,oBAAA,CACA,0BAAA,CACA,uCACF,CAAA,CASaC,EAAoB,CAC/B,8BAAA,CACA,qBACF,CAAA,CAKaC,CAAAA,CAAqB,CAChC,qCAAA,CACA,4BAAA,CACA,oCACF,CAAA,CASaC,CAAAA,CAAwB,CACnC,GAAI,SAAA,CACJ,OAAA,CAAS,UACT,EAAA,CAAI,WACN,EAKaC,CAAAA,CAAyB,CACpC,EAAA,CAAI,SAAA,CACJ,OAAA,CAAS,WAAA,CACT,GAAI,SACN,CAAA,CASaC,EAAmB,CAC9B,cAAA,CACA,cACF,CAAA,CAKaC,CAAAA,CAAoB,CAC/B,EAAA,CAAI,SAAA,CACJ,OAAA,CAAS,YACT,EAAA,CAAI,WACN,EAKaC,CAAAA,CAAgB,CAC3B,GAAI,KAAA,CACJ,OAAA,CAAS,MAAA,CACT,EAAA,CAAI,MACN,CAAA,CASaC,EAAqB,CAChC,MAAA,CACA,eACA,SAAA,CACA,sCACF,EAKaC,CAAAA,CAAuB,CAClC,MAAA,CACA,cAAA,CACA,SAAA,CACA,kCACF,EAKaC,CAAAA,CAAmB,CAC9B,0BACF,CAAA,CAKaC,CAAAA,CAAa,CACxB,aAAA,CACA,kCACF,CAAA,CAKaC,CAAAA,CAAqB,6EAAA,CASrBC,CAAAA,CAAuB,CAClC,4BAAA,CACA,2BAAA,CACA,4BACF,CAAA,CAKaC,CAAAA,CAAwB,CACnC,4BAAA,CACA,2BAAA,CACA,4BACF,CAAA,CAKaC,CAAAA,CAAiB,CAC5B,gCACA,4BACF,CAAA,CAKaC,EAAoB,CAC/B,mBAAA,CACA,cACF,CAAA,CAKaC,CAAAA,CAAkB,CAC7B,mBAAA,CACA,cACF,CAAA,CASaC,EAAe,CAC1B,0BAAA,CACA,uCACF,EASO,SAASC,KAAiBC,CAAAA,CAAkD,CACjF,OAAOA,CAAAA,CAAO,OAAA,CAAQC,CAAAA,EAAK,MAAM,OAAA,CAAQA,CAAC,EAAI,CAAC,GAAGA,CAAC,CAAA,CAAI,CAACA,CAAC,CAAC,CAC5D","file":"index.js","sourcesContent":["/**\n * Global Interaction State Styles\n *\n * Consistent interaction patterns across all Themis components.\n * These styles ensure WCAG 2.2 AAA compliance and predictable UX.\n *\n * @see spec.md FR-010 (Visible focus ring for keyboard navigation)\n * @see spec.md FR-031 (Pressed state feedback)\n * @see spec.md FR-012 (High contrast mode support)\n * @see constitution.md Principle IV (Accessibility First)\n */\n\n/**\n * Focus state styles (FR-010)\n * Visible focus ring for keyboard navigation - WCAG 2.2 Level AAA\n *\n * Components can override by extending these styles:\n * @example\n * cn(FOCUS_STYLES, \"ring-4\") // Increases ring width to 4px\n */\nexport const FOCUS_STYLES = \"data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2\";\n\n/**\n * Pressed/Active state styles (FR-031)\n * Visual feedback for press interactions\n *\n * Components can override the scale amount:\n * @example\n * cn(PRESSED_STYLES_BASE, \"data-[pressed]:scale-[0.95]\") // More pronounced scale\n */\nexport const PRESSED_STYLES = \"data-[pressed]:scale-[0.97]\";\n\n/**\n * Base pressed styles without scale (for components that need different feedback)\n */\nexport const PRESSED_STYLES_BASE = \"data-[pressed]:transition-transform data-[pressed]:duration-100\";\n\n/**\n * Hover state styles\n * Elevation change on hover for better affordance\n *\n * Components can override shadow depth:\n * @example\n * cn(HOVER_STYLES_BASE, \"data-[hovered]:shadow-lg\") // Larger shadow\n */\nexport const HOVER_STYLES = \"data-[hovered]:shadow-md\";\n\n/**\n * Base hover styles without shadow (for components that use different hover effects)\n */\nexport const HOVER_STYLES_BASE = \"data-[hovered]:transition-shadow data-[hovered]:duration-200\";\n\n/**\n * High contrast mode focus (FR-012)\n * Enhanced outlines for users requiring high contrast\n *\n * Uses 'hc:' prefix for prefers-contrast: more media query\n */\nexport const HIGH_CONTRAST_FOCUS = \"hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground\";\n\n/**\n * High contrast mode hover (FR-012)\n * Enhanced outlines for hover in high contrast mode\n */\nexport const HIGH_CONTRAST_HOVER = \"hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground\";\n\n/**\n * High contrast mode pressed state\n * Enhanced outlines for pressed state in high contrast mode\n */\nexport const HIGH_CONTRAST_PRESSED = \"hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground\";\n\n/**\n * Combined high contrast styles\n * Use this for components that need all high contrast interaction states\n */\nexport const HIGH_CONTRAST_INTERACTIONS = `${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Disabled state styles\n * Consistent disabled appearance across all components\n */\nexport const DISABLED_STYLES = \"disabled:pointer-events-none disabled:opacity-50\";\n\n/**\n * Default interaction bundle\n * Most common combination for interactive components\n *\n * Includes: focus ring, pressed scale, hover shadow, high contrast enhancements\n *\n * @example\n * <button className={cn(DEFAULT_INTERACTIONS, \"bg-primary\")}>Click</button>\n */\nexport const DEFAULT_INTERACTIONS = `${FOCUS_STYLES} ${PRESSED_STYLES} ${HOVER_STYLES} ${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Subtle interaction bundle\n * For components that need less pronounced feedback\n *\n * Includes: focus ring and high contrast, but no hover shadow or pressed scale\n */\nexport const SUBTLE_INTERACTIONS = `${FOCUS_STYLES} ${HIGH_CONTRAST_FOCUS}`;\n\n/**\n * Non-interactive element styles\n * For elements that should indicate they are not interactive\n */\nexport const NON_INTERACTIVE = \"cursor-default select-none\";\n","/**\n * Shared CVA Variant Utilities\n *\n * Common patterns extracted from component variants for consistency and reduced bundle size.\n * Use these constants in CVA definitions to ensure consistent styling across Themis.\n *\n * @see interaction-states.ts for interaction-specific styles (focus, hover, pressed)\n */\n\n// =============================================================================\n// Focus Ring Patterns\n// =============================================================================\n\n/**\n * Focus-within ring (for container elements with focusable children)\n * Use when the container should show focus when any child is focused\n */\nexport const FOCUS_WITHIN_RING = [\n 'focus-within:outline-none',\n 'focus-within:ring-2',\n 'focus-within:ring-[var(--ring)]',\n 'focus-within:ring-offset-2',\n] as const;\n\n/**\n * Focus-visible ring (for directly focusable elements)\n * Use for buttons, inputs, and other interactive elements\n */\nexport const FOCUS_VISIBLE_RING = [\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-[var(--ring)]',\n 'focus-visible:ring-offset-2',\n] as const;\n\n/**\n * Standard focus ring (for elements using :focus pseudo-class)\n * Prefer focus-visible when possible for better UX\n */\nexport const FOCUS_RING = [\n 'focus:outline-none',\n 'focus:ring-2',\n 'focus:ring-[var(--ring)]',\n] as const;\n\n/**\n * Focus with background change (for segments, cells, menu items)\n */\nexport const FOCUS_HIGHLIGHT = [\n 'focus:outline-none',\n 'focus:bg-[var(--accent)]',\n 'focus:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Disabled State Patterns\n// =============================================================================\n\n/**\n * Standard disabled state using disabled attribute\n */\nexport const DISABLED_STANDARD = [\n 'disabled:pointer-events-none',\n 'disabled:opacity-50',\n] as const;\n\n/**\n * Disabled state using data attribute (React Aria pattern)\n */\nexport const DISABLED_DATA_ATTR = [\n 'data-[disabled]:pointer-events-none',\n 'data-[disabled]:opacity-50',\n 'data-[disabled]:cursor-not-allowed',\n] as const;\n\n// =============================================================================\n// Size-Based Text Variants\n// =============================================================================\n\n/**\n * Small text size scale (xs -> sm -> base)\n */\nexport const TEXT_SIZE_SMALL_SCALE = {\n sm: 'text-xs',\n default: 'text-sm',\n lg: 'text-base',\n} as const;\n\n/**\n * Medium text size scale (sm -> base -> lg)\n */\nexport const TEXT_SIZE_MEDIUM_SCALE = {\n sm: 'text-sm',\n default: 'text-base',\n lg: 'text-lg',\n} as const;\n\n// =============================================================================\n// Touch Target Utilities\n// =============================================================================\n\n/**\n * WCAG 2.2 AAA minimum touch target (44x44px)\n */\nexport const TOUCH_TARGET_MIN = [\n 'min-h-[44px]',\n 'min-w-[44px]',\n] as const;\n\n/**\n * Common button/cell sizes with touch target compliance\n */\nexport const INTERACTIVE_SIZES = {\n sm: 'h-9 w-9', // 36px - desktop only, NOT AAA compliant\n default: 'h-11 w-11', // 44px - AAA compliant\n lg: 'h-14 w-14', // 56px - AAA compliant, enhanced\n} as const;\n\n/**\n * Height-only sizes for fields and inputs\n */\nexport const FIELD_HEIGHTS = {\n sm: 'h-9', // 36px\n default: 'h-11', // 44px\n lg: 'h-14', // 56px\n} as const;\n\n// =============================================================================\n// Message/Feedback Patterns\n// =============================================================================\n\n/**\n * Error message styling\n */\nexport const ERROR_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--destructive-background)]',\n] as const;\n\n/**\n * Success message styling\n */\nexport const SUCCESS_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--success-background)]',\n] as const;\n\n/**\n * Description/helper text styling\n */\nexport const DESCRIPTION_BASE = [\n 'text-[var(--menu-muted)]',\n] as const;\n\n/**\n * Label base styling\n */\nexport const LABEL_BASE = [\n 'font-medium',\n 'text-[var(--content-foreground)]',\n] as const;\n\n/**\n * Required indicator pattern\n */\nexport const REQUIRED_INDICATOR = \"after:content-['*'] after:ml-0.5 after:text-[var(--destructive-background)]\";\n\n// =============================================================================\n// Animation Patterns\n// =============================================================================\n\n/**\n * Popover/dropdown entry animation\n */\nexport const POPOVER_ANIMATION_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:zoom-in-95',\n] as const;\n\n/**\n * Popover/dropdown exit animation\n */\nexport const POPOVER_ANIMATION_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:zoom-out-95',\n] as const;\n\n/**\n * Reduced motion support (WCAG 2.2)\n */\nexport const REDUCED_MOTION = [\n 'motion-reduce:transition-none',\n 'motion-reduce:animate-none',\n] as const;\n\n/**\n * Standard transition for colors\n */\nexport const TRANSITION_COLORS = [\n 'transition-colors',\n 'duration-200',\n] as const;\n\n/**\n * Fast transition for interactions\n */\nexport const TRANSITION_FAST = [\n 'transition-colors',\n 'duration-150',\n] as const;\n\n// =============================================================================\n// Hover State Patterns\n// =============================================================================\n\n/**\n * Accent background on hover (for interactive items)\n */\nexport const HOVER_ACCENT = [\n 'hover:bg-[var(--accent)]',\n 'hover:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Combines multiple style arrays into a flat array for CVA base styles\n */\nexport function combineStyles(...styles: (readonly string[] | string)[]): string[] {\n return styles.flatMap(s => Array.isArray(s) ? [...s] : [s]);\n}\n"]}
|
package/dist/styles/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e="data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2",a="data-[pressed]:scale-[0.97]",E="data-[pressed]:transition-transform data-[pressed]:duration-100",r="data-[hovered]:shadow-md",
|
|
1
|
+
var e="data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2",a="data-[pressed]:scale-[0.97]",E="data-[pressed]:transition-transform data-[pressed]:duration-100",r="data-[hovered]:shadow-md",c="data-[hovered]:transition-shadow data-[hovered]:duration-200",t="hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground",n="hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground",s="hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground",i=`${t} ${n} ${s}`,_="disabled:pointer-events-none disabled:opacity-50",T=`${e} ${a} ${r} ${t} ${n} ${s}`,I=`${e} ${t}`,d="cursor-default select-none";var A=["focus-within:outline-none","focus-within:ring-2","focus-within:ring-[var(--ring)]","focus-within:ring-offset-2"],O=["focus-visible:outline-none","focus-visible:ring-2","focus-visible:ring-[var(--ring)]","focus-visible:ring-offset-2"],R=["focus:outline-none","focus:ring-2","focus:ring-[var(--ring)]"],u=["focus:outline-none","focus:bg-[var(--accent)]","focus:text-[var(--accent-foreground)]"],N=["disabled:pointer-events-none","disabled:opacity-50"],x=["data-[disabled]:pointer-events-none","data-[disabled]:opacity-50","data-[disabled]:cursor-not-allowed"],l={sm:"text-xs",default:"text-sm",lg:"text-base"},p={sm:"text-sm",default:"text-base",lg:"text-lg"},f=["min-h-[44px]","min-w-[44px]"],C={sm:"h-9 w-9",default:"h-11 w-11",lg:"h-14 w-14"},g={sm:"h-9",default:"h-11",lg:"h-14"},L=["flex","items-center","gap-1.5","text-[var(--destructive-background)]"],D=["flex","items-center","gap-1.5","text-[var(--success-background)]"],H=["text-[var(--menu-muted)]"],v=["font-medium","text-[var(--content-foreground)]"],h="after:content-['*'] after:ml-0.5 after:text-[var(--destructive-background)]",m=["data-[entering]:animate-in","data-[entering]:fade-in-0","data-[entering]:zoom-in-95"],U=["data-[exiting]:animate-out","data-[exiting]:fade-out-0","data-[exiting]:zoom-out-95"],b=["motion-reduce:transition-none","motion-reduce:animate-none"],G=["transition-colors","duration-200"],B=["transition-colors","duration-150"],M=["hover:bg-[var(--accent)]","hover:text-[var(--accent-foreground)]"];function F(...S){return S.flatMap(o=>Array.isArray(o)?[...o]:[o])}export{T as DEFAULT_INTERACTIONS,H as DESCRIPTION_BASE,x as DISABLED_DATA_ATTR,N as DISABLED_STANDARD,_ as DISABLED_STYLES,L as ERROR_MESSAGE_BASE,g as FIELD_HEIGHTS,u as FOCUS_HIGHLIGHT,R as FOCUS_RING,e as FOCUS_STYLES,O as FOCUS_VISIBLE_RING,A as FOCUS_WITHIN_RING,t as HIGH_CONTRAST_FOCUS,n as HIGH_CONTRAST_HOVER,i as HIGH_CONTRAST_INTERACTIONS,s as HIGH_CONTRAST_PRESSED,M as HOVER_ACCENT,r as HOVER_STYLES,c as HOVER_STYLES_BASE,C as INTERACTIVE_SIZES,v as LABEL_BASE,d as NON_INTERACTIVE,m as POPOVER_ANIMATION_IN,U as POPOVER_ANIMATION_OUT,a as PRESSED_STYLES,E as PRESSED_STYLES_BASE,b as REDUCED_MOTION,h as REQUIRED_INDICATOR,I as SUBTLE_INTERACTIONS,D as SUCCESS_MESSAGE_BASE,p as TEXT_SIZE_MEDIUM_SCALE,l as TEXT_SIZE_SMALL_SCALE,f as TOUCH_TARGET_MIN,G as TRANSITION_COLORS,B as TRANSITION_FAST,F as combineStyles};//# sourceMappingURL=index.mjs.map
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/styles/interaction-states.ts","../../src/styles/shared-variants.ts"],"names":["FOCUS_STYLES","PRESSED_STYLES","PRESSED_STYLES_BASE","HOVER_STYLES","HOVER_STYLES_BASE","HIGH_CONTRAST_FOCUS","HIGH_CONTRAST_HOVER","HIGH_CONTRAST_PRESSED","HIGH_CONTRAST_INTERACTIONS","DISABLED_STYLES","DEFAULT_INTERACTIONS","SUBTLE_INTERACTIONS","NON_INTERACTIVE","FOCUS_WITHIN_RING","FOCUS_VISIBLE_RING","FOCUS_RING","FOCUS_HIGHLIGHT","DISABLED_STANDARD","DISABLED_DATA_ATTR","TEXT_SIZE_SMALL_SCALE","TEXT_SIZE_MEDIUM_SCALE","TOUCH_TARGET_MIN","INTERACTIVE_SIZES","FIELD_HEIGHTS","ERROR_MESSAGE_BASE","SUCCESS_MESSAGE_BASE","DESCRIPTION_BASE","LABEL_BASE","REQUIRED_INDICATOR","POPOVER_ANIMATION_IN","POPOVER_ANIMATION_OUT","REDUCED_MOTION","TRANSITION_COLORS","TRANSITION_FAST","HOVER_ACCENT","combineStyles","styles","s"],"mappings":"AAoBO,IAAMA,CAAAA,CAAe,gHAUfC,CAAAA,CAAiB,6BAAA,CAKjBC,EAAsB,iEAAA,CAUtBC,CAAAA,CAAe,2BAKfC,CAAAA,CAAoB,8DAAA,CAQpBC,EAAsB,uJAAA,CAMtBC,CAAAA,CAAsB,6FAMtBC,CAAAA,CAAwB,+HAAA,CAMxBC,EAA6B,CAAA,EAAGH,CAAmB,CAAA,CAAA,EAAIC,CAAmB,CAAA,CAAA,EAAIC,CAAqB,GAMnGE,CAAAA,CAAkB,kDAAA,CAWlBC,EAAuB,CAAA,EAAGV,CAAY,IAAIC,CAAc,CAAA,CAAA,EAAIE,CAAY,CAAA,CAAA,EAAIE,CAAmB,CAAA,CAAA,EAAIC,CAAmB,CAAA,CAAA,EAAIC,CAAqB,GAQ/II,CAAAA,CAAsB,CAAA,EAAGX,CAAY,CAAA,CAAA,EAAIK,CAAmB,CAAA,CAAA,CAM5DO,CAAAA,CAAkB,6BC1FxB,IAAMC,EAAoB,CAC/B,2BAAA,CACA,sBACA,iCAAA,CACA,4BACF,EAMaC,CAAAA,CAAqB,CAChC,4BAAA,CACA,sBAAA,CACA,kCAAA,CACA,6BACF,EAMaC,CAAAA,CAAa,CACxB,qBACA,cAAA,CACA,0BACF,EAKaC,CAAAA,CAAkB,CAC7B,oBAAA,CACA,0BAAA,CACA,uCACF,CAAA,CASaC,EAAoB,CAC/B,8BAAA,CACA,qBACF,CAAA,CAKaC,CAAAA,CAAqB,CAChC,qCAAA,CACA,4BAAA,CACA,oCACF,CAAA,CASaC,CAAAA,CAAwB,CACnC,GAAI,SAAA,CACJ,OAAA,CAAS,UACT,EAAA,CAAI,WACN,EAKaC,CAAAA,CAAyB,CACpC,EAAA,CAAI,SAAA,CACJ,OAAA,CAAS,WAAA,CACT,GAAI,SACN,CAAA,CASaC,EAAmB,CAC9B,cAAA,CACA,cACF,CAAA,CAKaC,CAAAA,CAAoB,CAC/B,EAAA,CAAI,SAAA,CACJ,OAAA,CAAS,YACT,EAAA,CAAI,WACN,EAKaC,CAAAA,CAAgB,CAC3B,GAAI,KAAA,CACJ,OAAA,CAAS,MAAA,CACT,EAAA,CAAI,MACN,CAAA,CASaC,EAAqB,CAChC,MAAA,CACA,eACA,SAAA,CACA,2BACF,EAKaC,CAAAA,CAAuB,CAClC,MAAA,CACA,cAAA,CACA,SAAA,CACA,uBACF,EAKaC,CAAAA,CAAmB,CAC9B,0BACF,CAAA,CAKaC,CAAAA,CAAa,CACxB,aAAA,CACA,kCACF,CAAA,CAKaC,CAAAA,CAAqB,kEAAA,CASrBC,CAAAA,CAAuB,CAClC,4BAAA,CACA,2BAAA,CACA,4BACF,CAAA,CAKaC,CAAAA,CAAwB,CACnC,4BAAA,CACA,2BAAA,CACA,4BACF,CAAA,CAKaC,CAAAA,CAAiB,CAC5B,gCACA,4BACF,CAAA,CAKaC,EAAoB,CAC/B,mBAAA,CACA,cACF,CAAA,CAKaC,CAAAA,CAAkB,CAC7B,mBAAA,CACA,cACF,CAAA,CASaC,EAAe,CAC1B,0BAAA,CACA,uCACF,EASO,SAASC,KAAiBC,CAAAA,CAAkD,CACjF,OAAOA,CAAAA,CAAO,OAAA,CAAQC,CAAAA,EAAK,MAAM,OAAA,CAAQA,CAAC,EAAI,CAAC,GAAGA,CAAC,CAAA,CAAI,CAACA,CAAC,CAAC,CAC5D","file":"index.mjs","sourcesContent":["/**\n * Global Interaction State Styles\n *\n * Consistent interaction patterns across all Themis components.\n * These styles ensure WCAG 2.2 AAA compliance and predictable UX.\n *\n * @see spec.md FR-010 (Visible focus ring for keyboard navigation)\n * @see spec.md FR-031 (Pressed state feedback)\n * @see spec.md FR-012 (High contrast mode support)\n * @see constitution.md Principle IV (Accessibility First)\n */\n\n/**\n * Focus state styles (FR-010)\n * Visible focus ring for keyboard navigation - WCAG 2.2 Level AAA\n *\n * Components can override by extending these styles:\n * @example\n * cn(FOCUS_STYLES, \"ring-4\") // Increases ring width to 4px\n */\nexport const FOCUS_STYLES = \"data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2\";\n\n/**\n * Pressed/Active state styles (FR-031)\n * Visual feedback for press interactions\n *\n * Components can override the scale amount:\n * @example\n * cn(PRESSED_STYLES_BASE, \"data-[pressed]:scale-[0.95]\") // More pronounced scale\n */\nexport const PRESSED_STYLES = \"data-[pressed]:scale-[0.97]\";\n\n/**\n * Base pressed styles without scale (for components that need different feedback)\n */\nexport const PRESSED_STYLES_BASE = \"data-[pressed]:transition-transform data-[pressed]:duration-100\";\n\n/**\n * Hover state styles\n * Elevation change on hover for better affordance\n *\n * Components can override shadow depth:\n * @example\n * cn(HOVER_STYLES_BASE, \"data-[hovered]:shadow-lg\") // Larger shadow\n */\nexport const HOVER_STYLES = \"data-[hovered]:shadow-md\";\n\n/**\n * Base hover styles without shadow (for components that use different hover effects)\n */\nexport const HOVER_STYLES_BASE = \"data-[hovered]:transition-shadow data-[hovered]:duration-200\";\n\n/**\n * High contrast mode focus (FR-012)\n * Enhanced outlines for users requiring high contrast\n *\n * Uses 'hc:' prefix for prefers-contrast: more media query\n */\nexport const HIGH_CONTRAST_FOCUS = \"hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground\";\n\n/**\n * High contrast mode hover (FR-012)\n * Enhanced outlines for hover in high contrast mode\n */\nexport const HIGH_CONTRAST_HOVER = \"hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground\";\n\n/**\n * High contrast mode pressed state\n * Enhanced outlines for pressed state in high contrast mode\n */\nexport const HIGH_CONTRAST_PRESSED = \"hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground\";\n\n/**\n * Combined high contrast styles\n * Use this for components that need all high contrast interaction states\n */\nexport const HIGH_CONTRAST_INTERACTIONS = `${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Disabled state styles\n * Consistent disabled appearance across all components\n */\nexport const DISABLED_STYLES = \"disabled:pointer-events-none disabled:opacity-50\";\n\n/**\n * Default interaction bundle\n * Most common combination for interactive components\n *\n * Includes: focus ring, pressed scale, hover shadow, high contrast enhancements\n *\n * @example\n * <button className={cn(DEFAULT_INTERACTIONS, \"bg-primary\")}>Click</button>\n */\nexport const DEFAULT_INTERACTIONS = `${FOCUS_STYLES} ${PRESSED_STYLES} ${HOVER_STYLES} ${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Subtle interaction bundle\n * For components that need less pronounced feedback\n *\n * Includes: focus ring and high contrast, but no hover shadow or pressed scale\n */\nexport const SUBTLE_INTERACTIONS = `${FOCUS_STYLES} ${HIGH_CONTRAST_FOCUS}`;\n\n/**\n * Non-interactive element styles\n * For elements that should indicate they are not interactive\n */\nexport const NON_INTERACTIVE = \"cursor-default select-none\";\n","/**\n * Shared CVA Variant Utilities\n *\n * Common patterns extracted from component variants for consistency and reduced bundle size.\n * Use these constants in CVA definitions to ensure consistent styling across Themis.\n *\n * @see interaction-states.ts for interaction-specific styles (focus, hover, pressed)\n */\n\n// =============================================================================\n// Focus Ring Patterns\n// =============================================================================\n\n/**\n * Focus-within ring (for container elements with focusable children)\n * Use when the container should show focus when any child is focused\n */\nexport const FOCUS_WITHIN_RING = [\n 'focus-within:outline-none',\n 'focus-within:ring-2',\n 'focus-within:ring-[var(--ring)]',\n 'focus-within:ring-offset-2',\n] as const;\n\n/**\n * Focus-visible ring (for directly focusable elements)\n * Use for buttons, inputs, and other interactive elements\n */\nexport const FOCUS_VISIBLE_RING = [\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-[var(--ring)]',\n 'focus-visible:ring-offset-2',\n] as const;\n\n/**\n * Standard focus ring (for elements using :focus pseudo-class)\n * Prefer focus-visible when possible for better UX\n */\nexport const FOCUS_RING = [\n 'focus:outline-none',\n 'focus:ring-2',\n 'focus:ring-[var(--ring)]',\n] as const;\n\n/**\n * Focus with background change (for segments, cells, menu items)\n */\nexport const FOCUS_HIGHLIGHT = [\n 'focus:outline-none',\n 'focus:bg-[var(--accent)]',\n 'focus:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Disabled State Patterns\n// =============================================================================\n\n/**\n * Standard disabled state using disabled attribute\n */\nexport const DISABLED_STANDARD = [\n 'disabled:pointer-events-none',\n 'disabled:opacity-50',\n] as const;\n\n/**\n * Disabled state using data attribute (React Aria pattern)\n */\nexport const DISABLED_DATA_ATTR = [\n 'data-[disabled]:pointer-events-none',\n 'data-[disabled]:opacity-50',\n 'data-[disabled]:cursor-not-allowed',\n] as const;\n\n// =============================================================================\n// Size-Based Text Variants\n// =============================================================================\n\n/**\n * Small text size scale (xs -> sm -> base)\n */\nexport const TEXT_SIZE_SMALL_SCALE = {\n sm: 'text-xs',\n default: 'text-sm',\n lg: 'text-base',\n} as const;\n\n/**\n * Medium text size scale (sm -> base -> lg)\n */\nexport const TEXT_SIZE_MEDIUM_SCALE = {\n sm: 'text-sm',\n default: 'text-base',\n lg: 'text-lg',\n} as const;\n\n// =============================================================================\n// Touch Target Utilities\n// =============================================================================\n\n/**\n * WCAG 2.2 AAA minimum touch target (44x44px)\n */\nexport const TOUCH_TARGET_MIN = [\n 'min-h-[44px]',\n 'min-w-[44px]',\n] as const;\n\n/**\n * Common button/cell sizes with touch target compliance\n */\nexport const INTERACTIVE_SIZES = {\n sm: 'h-9 w-9', // 36px - desktop only, NOT AAA compliant\n default: 'h-11 w-11', // 44px - AAA compliant\n lg: 'h-14 w-14', // 56px - AAA compliant, enhanced\n} as const;\n\n/**\n * Height-only sizes for fields and inputs\n */\nexport const FIELD_HEIGHTS = {\n sm: 'h-9', // 36px\n default: 'h-11', // 44px\n lg: 'h-14', // 56px\n} as const;\n\n// =============================================================================\n// Message/Feedback Patterns\n// =============================================================================\n\n/**\n * Error message styling\n */\nexport const ERROR_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--destructive)]',\n] as const;\n\n/**\n * Success message styling\n */\nexport const SUCCESS_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--success)]',\n] as const;\n\n/**\n * Description/helper text styling\n */\nexport const DESCRIPTION_BASE = [\n 'text-[var(--menu-muted)]',\n] as const;\n\n/**\n * Label base styling\n */\nexport const LABEL_BASE = [\n 'font-medium',\n 'text-[var(--content-foreground)]',\n] as const;\n\n/**\n * Required indicator pattern\n */\nexport const REQUIRED_INDICATOR = \"after:content-['*'] after:ml-0.5 after:text-[var(--destructive)]\";\n\n// =============================================================================\n// Animation Patterns\n// =============================================================================\n\n/**\n * Popover/dropdown entry animation\n */\nexport const POPOVER_ANIMATION_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:zoom-in-95',\n] as const;\n\n/**\n * Popover/dropdown exit animation\n */\nexport const POPOVER_ANIMATION_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:zoom-out-95',\n] as const;\n\n/**\n * Reduced motion support (WCAG 2.2)\n */\nexport const REDUCED_MOTION = [\n 'motion-reduce:transition-none',\n 'motion-reduce:animate-none',\n] as const;\n\n/**\n * Standard transition for colors\n */\nexport const TRANSITION_COLORS = [\n 'transition-colors',\n 'duration-200',\n] as const;\n\n/**\n * Fast transition for interactions\n */\nexport const TRANSITION_FAST = [\n 'transition-colors',\n 'duration-150',\n] as const;\n\n// =============================================================================\n// Hover State Patterns\n// =============================================================================\n\n/**\n * Accent background on hover (for interactive items)\n */\nexport const HOVER_ACCENT = [\n 'hover:bg-[var(--accent)]',\n 'hover:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Combines multiple style arrays into a flat array for CVA base styles\n */\nexport function combineStyles(...styles: (readonly string[] | string)[]): string[] {\n return styles.flatMap(s => Array.isArray(s) ? [...s] : [s]);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/styles/interaction-states.ts","../../src/styles/shared-variants.ts"],"names":["FOCUS_STYLES","PRESSED_STYLES","PRESSED_STYLES_BASE","HOVER_STYLES","HOVER_STYLES_BASE","HIGH_CONTRAST_FOCUS","HIGH_CONTRAST_HOVER","HIGH_CONTRAST_PRESSED","HIGH_CONTRAST_INTERACTIONS","DISABLED_STYLES","DEFAULT_INTERACTIONS","SUBTLE_INTERACTIONS","NON_INTERACTIVE","FOCUS_WITHIN_RING","FOCUS_VISIBLE_RING","FOCUS_RING","FOCUS_HIGHLIGHT","DISABLED_STANDARD","DISABLED_DATA_ATTR","TEXT_SIZE_SMALL_SCALE","TEXT_SIZE_MEDIUM_SCALE","TOUCH_TARGET_MIN","INTERACTIVE_SIZES","FIELD_HEIGHTS","ERROR_MESSAGE_BASE","SUCCESS_MESSAGE_BASE","DESCRIPTION_BASE","LABEL_BASE","REQUIRED_INDICATOR","POPOVER_ANIMATION_IN","POPOVER_ANIMATION_OUT","REDUCED_MOTION","TRANSITION_COLORS","TRANSITION_FAST","HOVER_ACCENT","combineStyles","styles","s"],"mappings":"AAoBO,IAAMA,CAAAA,CAAe,gHAUfC,CAAAA,CAAiB,6BAAA,CAKjBC,EAAsB,iEAAA,CAUtBC,CAAAA,CAAe,2BAKfC,CAAAA,CAAoB,8DAAA,CAQpBC,EAAsB,uJAAA,CAMtBC,CAAAA,CAAsB,6FAMtBC,CAAAA,CAAwB,+HAAA,CAMxBC,EAA6B,CAAA,EAAGH,CAAmB,CAAA,CAAA,EAAIC,CAAmB,CAAA,CAAA,EAAIC,CAAqB,GAMnGE,CAAAA,CAAkB,kDAAA,CAWlBC,EAAuB,CAAA,EAAGV,CAAY,IAAIC,CAAc,CAAA,CAAA,EAAIE,CAAY,CAAA,CAAA,EAAIE,CAAmB,CAAA,CAAA,EAAIC,CAAmB,CAAA,CAAA,EAAIC,CAAqB,GAQ/II,CAAAA,CAAsB,CAAA,EAAGX,CAAY,CAAA,CAAA,EAAIK,CAAmB,CAAA,CAAA,CAM5DO,CAAAA,CAAkB,6BC1FxB,IAAMC,EAAoB,CAC/B,2BAAA,CACA,sBACA,iCAAA,CACA,4BACF,EAMaC,CAAAA,CAAqB,CAChC,4BAAA,CACA,sBAAA,CACA,kCAAA,CACA,6BACF,EAMaC,CAAAA,CAAa,CACxB,qBACA,cAAA,CACA,0BACF,EAKaC,CAAAA,CAAkB,CAC7B,oBAAA,CACA,0BAAA,CACA,uCACF,CAAA,CASaC,EAAoB,CAC/B,8BAAA,CACA,qBACF,CAAA,CAKaC,CAAAA,CAAqB,CAChC,qCAAA,CACA,4BAAA,CACA,oCACF,CAAA,CASaC,CAAAA,CAAwB,CACnC,GAAI,SAAA,CACJ,OAAA,CAAS,UACT,EAAA,CAAI,WACN,EAKaC,CAAAA,CAAyB,CACpC,EAAA,CAAI,SAAA,CACJ,OAAA,CAAS,WAAA,CACT,GAAI,SACN,CAAA,CASaC,EAAmB,CAC9B,cAAA,CACA,cACF,CAAA,CAKaC,CAAAA,CAAoB,CAC/B,EAAA,CAAI,SAAA,CACJ,OAAA,CAAS,YACT,EAAA,CAAI,WACN,EAKaC,CAAAA,CAAgB,CAC3B,GAAI,KAAA,CACJ,OAAA,CAAS,MAAA,CACT,EAAA,CAAI,MACN,CAAA,CASaC,EAAqB,CAChC,MAAA,CACA,eACA,SAAA,CACA,sCACF,EAKaC,CAAAA,CAAuB,CAClC,MAAA,CACA,cAAA,CACA,SAAA,CACA,kCACF,EAKaC,CAAAA,CAAmB,CAC9B,0BACF,CAAA,CAKaC,CAAAA,CAAa,CACxB,aAAA,CACA,kCACF,CAAA,CAKaC,CAAAA,CAAqB,6EAAA,CASrBC,CAAAA,CAAuB,CAClC,4BAAA,CACA,2BAAA,CACA,4BACF,CAAA,CAKaC,CAAAA,CAAwB,CACnC,4BAAA,CACA,2BAAA,CACA,4BACF,CAAA,CAKaC,CAAAA,CAAiB,CAC5B,gCACA,4BACF,CAAA,CAKaC,EAAoB,CAC/B,mBAAA,CACA,cACF,CAAA,CAKaC,CAAAA,CAAkB,CAC7B,mBAAA,CACA,cACF,CAAA,CASaC,EAAe,CAC1B,0BAAA,CACA,uCACF,EASO,SAASC,KAAiBC,CAAAA,CAAkD,CACjF,OAAOA,CAAAA,CAAO,OAAA,CAAQC,CAAAA,EAAK,MAAM,OAAA,CAAQA,CAAC,EAAI,CAAC,GAAGA,CAAC,CAAA,CAAI,CAACA,CAAC,CAAC,CAC5D","file":"index.mjs","sourcesContent":["/**\n * Global Interaction State Styles\n *\n * Consistent interaction patterns across all Themis components.\n * These styles ensure WCAG 2.2 AAA compliance and predictable UX.\n *\n * @see spec.md FR-010 (Visible focus ring for keyboard navigation)\n * @see spec.md FR-031 (Pressed state feedback)\n * @see spec.md FR-012 (High contrast mode support)\n * @see constitution.md Principle IV (Accessibility First)\n */\n\n/**\n * Focus state styles (FR-010)\n * Visible focus ring for keyboard navigation - WCAG 2.2 Level AAA\n *\n * Components can override by extending these styles:\n * @example\n * cn(FOCUS_STYLES, \"ring-4\") // Increases ring width to 4px\n */\nexport const FOCUS_STYLES = \"data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2\";\n\n/**\n * Pressed/Active state styles (FR-031)\n * Visual feedback for press interactions\n *\n * Components can override the scale amount:\n * @example\n * cn(PRESSED_STYLES_BASE, \"data-[pressed]:scale-[0.95]\") // More pronounced scale\n */\nexport const PRESSED_STYLES = \"data-[pressed]:scale-[0.97]\";\n\n/**\n * Base pressed styles without scale (for components that need different feedback)\n */\nexport const PRESSED_STYLES_BASE = \"data-[pressed]:transition-transform data-[pressed]:duration-100\";\n\n/**\n * Hover state styles\n * Elevation change on hover for better affordance\n *\n * Components can override shadow depth:\n * @example\n * cn(HOVER_STYLES_BASE, \"data-[hovered]:shadow-lg\") // Larger shadow\n */\nexport const HOVER_STYLES = \"data-[hovered]:shadow-md\";\n\n/**\n * Base hover styles without shadow (for components that use different hover effects)\n */\nexport const HOVER_STYLES_BASE = \"data-[hovered]:transition-shadow data-[hovered]:duration-200\";\n\n/**\n * High contrast mode focus (FR-012)\n * Enhanced outlines for users requiring high contrast\n *\n * Uses 'hc:' prefix for prefers-contrast: more media query\n */\nexport const HIGH_CONTRAST_FOCUS = \"hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground\";\n\n/**\n * High contrast mode hover (FR-012)\n * Enhanced outlines for hover in high contrast mode\n */\nexport const HIGH_CONTRAST_HOVER = \"hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground\";\n\n/**\n * High contrast mode pressed state\n * Enhanced outlines for pressed state in high contrast mode\n */\nexport const HIGH_CONTRAST_PRESSED = \"hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground\";\n\n/**\n * Combined high contrast styles\n * Use this for components that need all high contrast interaction states\n */\nexport const HIGH_CONTRAST_INTERACTIONS = `${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Disabled state styles\n * Consistent disabled appearance across all components\n */\nexport const DISABLED_STYLES = \"disabled:pointer-events-none disabled:opacity-50\";\n\n/**\n * Default interaction bundle\n * Most common combination for interactive components\n *\n * Includes: focus ring, pressed scale, hover shadow, high contrast enhancements\n *\n * @example\n * <button className={cn(DEFAULT_INTERACTIONS, \"bg-primary\")}>Click</button>\n */\nexport const DEFAULT_INTERACTIONS = `${FOCUS_STYLES} ${PRESSED_STYLES} ${HOVER_STYLES} ${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Subtle interaction bundle\n * For components that need less pronounced feedback\n *\n * Includes: focus ring and high contrast, but no hover shadow or pressed scale\n */\nexport const SUBTLE_INTERACTIONS = `${FOCUS_STYLES} ${HIGH_CONTRAST_FOCUS}`;\n\n/**\n * Non-interactive element styles\n * For elements that should indicate they are not interactive\n */\nexport const NON_INTERACTIVE = \"cursor-default select-none\";\n","/**\n * Shared CVA Variant Utilities\n *\n * Common patterns extracted from component variants for consistency and reduced bundle size.\n * Use these constants in CVA definitions to ensure consistent styling across Themis.\n *\n * @see interaction-states.ts for interaction-specific styles (focus, hover, pressed)\n */\n\n// =============================================================================\n// Focus Ring Patterns\n// =============================================================================\n\n/**\n * Focus-within ring (for container elements with focusable children)\n * Use when the container should show focus when any child is focused\n */\nexport const FOCUS_WITHIN_RING = [\n 'focus-within:outline-none',\n 'focus-within:ring-2',\n 'focus-within:ring-[var(--ring)]',\n 'focus-within:ring-offset-2',\n] as const;\n\n/**\n * Focus-visible ring (for directly focusable elements)\n * Use for buttons, inputs, and other interactive elements\n */\nexport const FOCUS_VISIBLE_RING = [\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-[var(--ring)]',\n 'focus-visible:ring-offset-2',\n] as const;\n\n/**\n * Standard focus ring (for elements using :focus pseudo-class)\n * Prefer focus-visible when possible for better UX\n */\nexport const FOCUS_RING = [\n 'focus:outline-none',\n 'focus:ring-2',\n 'focus:ring-[var(--ring)]',\n] as const;\n\n/**\n * Focus with background change (for segments, cells, menu items)\n */\nexport const FOCUS_HIGHLIGHT = [\n 'focus:outline-none',\n 'focus:bg-[var(--accent)]',\n 'focus:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Disabled State Patterns\n// =============================================================================\n\n/**\n * Standard disabled state using disabled attribute\n */\nexport const DISABLED_STANDARD = [\n 'disabled:pointer-events-none',\n 'disabled:opacity-50',\n] as const;\n\n/**\n * Disabled state using data attribute (React Aria pattern)\n */\nexport const DISABLED_DATA_ATTR = [\n 'data-[disabled]:pointer-events-none',\n 'data-[disabled]:opacity-50',\n 'data-[disabled]:cursor-not-allowed',\n] as const;\n\n// =============================================================================\n// Size-Based Text Variants\n// =============================================================================\n\n/**\n * Small text size scale (xs -> sm -> base)\n */\nexport const TEXT_SIZE_SMALL_SCALE = {\n sm: 'text-xs',\n default: 'text-sm',\n lg: 'text-base',\n} as const;\n\n/**\n * Medium text size scale (sm -> base -> lg)\n */\nexport const TEXT_SIZE_MEDIUM_SCALE = {\n sm: 'text-sm',\n default: 'text-base',\n lg: 'text-lg',\n} as const;\n\n// =============================================================================\n// Touch Target Utilities\n// =============================================================================\n\n/**\n * WCAG 2.2 AAA minimum touch target (44x44px)\n */\nexport const TOUCH_TARGET_MIN = [\n 'min-h-[44px]',\n 'min-w-[44px]',\n] as const;\n\n/**\n * Common button/cell sizes with touch target compliance\n */\nexport const INTERACTIVE_SIZES = {\n sm: 'h-9 w-9', // 36px - desktop only, NOT AAA compliant\n default: 'h-11 w-11', // 44px - AAA compliant\n lg: 'h-14 w-14', // 56px - AAA compliant, enhanced\n} as const;\n\n/**\n * Height-only sizes for fields and inputs\n */\nexport const FIELD_HEIGHTS = {\n sm: 'h-9', // 36px\n default: 'h-11', // 44px\n lg: 'h-14', // 56px\n} as const;\n\n// =============================================================================\n// Message/Feedback Patterns\n// =============================================================================\n\n/**\n * Error message styling\n */\nexport const ERROR_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--destructive-background)]',\n] as const;\n\n/**\n * Success message styling\n */\nexport const SUCCESS_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--success-background)]',\n] as const;\n\n/**\n * Description/helper text styling\n */\nexport const DESCRIPTION_BASE = [\n 'text-[var(--menu-muted)]',\n] as const;\n\n/**\n * Label base styling\n */\nexport const LABEL_BASE = [\n 'font-medium',\n 'text-[var(--content-foreground)]',\n] as const;\n\n/**\n * Required indicator pattern\n */\nexport const REQUIRED_INDICATOR = \"after:content-['*'] after:ml-0.5 after:text-[var(--destructive-background)]\";\n\n// =============================================================================\n// Animation Patterns\n// =============================================================================\n\n/**\n * Popover/dropdown entry animation\n */\nexport const POPOVER_ANIMATION_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:zoom-in-95',\n] as const;\n\n/**\n * Popover/dropdown exit animation\n */\nexport const POPOVER_ANIMATION_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:zoom-out-95',\n] as const;\n\n/**\n * Reduced motion support (WCAG 2.2)\n */\nexport const REDUCED_MOTION = [\n 'motion-reduce:transition-none',\n 'motion-reduce:animate-none',\n] as const;\n\n/**\n * Standard transition for colors\n */\nexport const TRANSITION_COLORS = [\n 'transition-colors',\n 'duration-200',\n] as const;\n\n/**\n * Fast transition for interactions\n */\nexport const TRANSITION_FAST = [\n 'transition-colors',\n 'duration-150',\n] as const;\n\n// =============================================================================\n// Hover State Patterns\n// =============================================================================\n\n/**\n * Accent background on hover (for interactive items)\n */\nexport const HOVER_ACCENT = [\n 'hover:bg-[var(--accent)]',\n 'hover:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Combines multiple style arrays into a flat array for CVA base styles\n */\nexport function combineStyles(...styles: (readonly string[] | string)[]): string[] {\n return styles.flatMap(s => Array.isArray(s) ? [...s] : [s]);\n}\n"]}
|
|
@@ -72,11 +72,11 @@ export declare const FIELD_HEIGHTS: {
|
|
|
72
72
|
/**
|
|
73
73
|
* Error message styling
|
|
74
74
|
*/
|
|
75
|
-
export declare const ERROR_MESSAGE_BASE: readonly ["flex", "items-center", "gap-1.5", "text-[var(--destructive)]"];
|
|
75
|
+
export declare const ERROR_MESSAGE_BASE: readonly ["flex", "items-center", "gap-1.5", "text-[var(--destructive-background)]"];
|
|
76
76
|
/**
|
|
77
77
|
* Success message styling
|
|
78
78
|
*/
|
|
79
|
-
export declare const SUCCESS_MESSAGE_BASE: readonly ["flex", "items-center", "gap-1.5", "text-[var(--success)]"];
|
|
79
|
+
export declare const SUCCESS_MESSAGE_BASE: readonly ["flex", "items-center", "gap-1.5", "text-[var(--success-background)]"];
|
|
80
80
|
/**
|
|
81
81
|
* Description/helper text styling
|
|
82
82
|
*/
|
|
@@ -88,7 +88,7 @@ export declare const LABEL_BASE: readonly ["font-medium", "text-[var(--content-f
|
|
|
88
88
|
/**
|
|
89
89
|
* Required indicator pattern
|
|
90
90
|
*/
|
|
91
|
-
export declare const REQUIRED_INDICATOR = "after:content-['*'] after:ml-0.5 after:text-[var(--destructive)]";
|
|
91
|
+
export declare const REQUIRED_INDICATOR = "after:content-['*'] after:ml-0.5 after:text-[var(--destructive-background)]";
|
|
92
92
|
/**
|
|
93
93
|
* Popover/dropdown entry animation
|
|
94
94
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared-variants.d.ts","sourceRoot":"","sources":["../../src/styles/shared-variants.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH;;;GAGG;AACH,eAAO,MAAM,iBAAiB,gIAKpB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,kBAAkB,oIAKrB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,UAAU,6EAIb,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,eAAe,sGAIlB,CAAC;AAMX;;GAEG;AACH,eAAO,MAAM,iBAAiB,kEAGpB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,kBAAkB,sHAIrB,CAAC;AAMX;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;;CAIxB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;CAIzB,CAAC;AAMX;;GAEG;AACH,eAAO,MAAM,gBAAgB,2CAGnB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;CAIpB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,aAAa;;;;CAIhB,CAAC;AAMX;;GAEG;AACH,eAAO,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"shared-variants.d.ts","sourceRoot":"","sources":["../../src/styles/shared-variants.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH;;;GAGG;AACH,eAAO,MAAM,iBAAiB,gIAKpB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,kBAAkB,oIAKrB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,UAAU,6EAIb,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,eAAe,sGAIlB,CAAC;AAMX;;GAEG;AACH,eAAO,MAAM,iBAAiB,kEAGpB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,kBAAkB,sHAIrB,CAAC;AAMX;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;;CAIxB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;CAIzB,CAAC;AAMX;;GAEG;AACH,eAAO,MAAM,gBAAgB,2CAGnB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;CAIpB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,aAAa;;;;CAIhB,CAAC;AAMX;;GAEG;AACH,eAAO,MAAM,kBAAkB,sFAKrB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,oBAAoB,kFAKvB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,gBAAgB,uCAEnB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,UAAU,8DAGb,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,kBAAkB,gFAAgF,CAAC;AAMhH;;GAEG;AACH,eAAO,MAAM,oBAAoB,oGAIvB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,qBAAqB,oGAIxB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,cAAc,0EAGjB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,iBAAiB,gDAGpB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,eAAe,gDAGlB,CAAC;AAMX;;GAEG;AACH,eAAO,MAAM,YAAY,gFAGf,CAAC;AAMX;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,MAAM,EAAE,CAAC,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,GAAG,MAAM,EAAE,CAEjF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tribepad/themis",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Accessible React component library built on React Aria primitives",
|
|
5
5
|
"author": "Tribepad <mbasford@tribepad.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -131,10 +131,9 @@
|
|
|
131
131
|
"devDependencies": {
|
|
132
132
|
"@eslint/js": "^9.0.0",
|
|
133
133
|
"@size-limit/preset-small-lib": "^11.0.0",
|
|
134
|
-
"@storybook/addon-a11y": "^
|
|
135
|
-
"@storybook/
|
|
136
|
-
"@
|
|
137
|
-
"storybook": "^8.0.0",
|
|
134
|
+
"@storybook/addon-a11y": "^10.2.8",
|
|
135
|
+
"@storybook/react-vite": "^10.2.8",
|
|
136
|
+
"@tailwindcss/vite": "^4.1.18",
|
|
138
137
|
"@testing-library/jest-dom": "^6.0.0",
|
|
139
138
|
"@testing-library/react": "^16.0.0",
|
|
140
139
|
"@testing-library/user-event": "^14.0.0",
|
|
@@ -155,6 +154,7 @@
|
|
|
155
154
|
"react": "^19.0.0",
|
|
156
155
|
"react-dom": "^19.0.0",
|
|
157
156
|
"size-limit": "^11.0.0",
|
|
157
|
+
"storybook": "^10.2.8",
|
|
158
158
|
"tsup": "^8.0.0",
|
|
159
159
|
"tsx": "^4.0.0",
|
|
160
160
|
"typescript": "^5.6.0",
|
|
@@ -738,7 +738,7 @@ export const PermissionsSettings: Story = {
|
|
|
738
738
|
</Checkbox>
|
|
739
739
|
<Checkbox value="delete" className="p-4">
|
|
740
740
|
<div className="flex w-full items-start gap-4">
|
|
741
|
-
<div className="flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-lg bg-[var(--destructive)]/10 text-xl">
|
|
741
|
+
<div className="flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-lg bg-[var(--destructive-background)]/10 text-xl">
|
|
742
742
|
🗑️
|
|
743
743
|
</div>
|
|
744
744
|
<div className="flex-1">
|
|
@@ -763,8 +763,8 @@ export const PermissionsSettings: Story = {
|
|
|
763
763
|
|
|
764
764
|
export const DangerZone: Story = {
|
|
765
765
|
render: () => (
|
|
766
|
-
<div className="w-96 rounded-lg border border-[var(--destructive)] bg-[var(--background)] p-6">
|
|
767
|
-
<h3 className="mb-4 text-lg font-semibold text-[var(--destructive)]">Danger Zone</h3>
|
|
766
|
+
<div className="w-96 rounded-lg border border-[var(--destructive-background)] bg-[var(--background)] p-6">
|
|
767
|
+
<h3 className="mb-4 text-lg font-semibold text-[var(--destructive-background)]">Danger Zone</h3>
|
|
768
768
|
<CheckboxGroup
|
|
769
769
|
variant="destructive"
|
|
770
770
|
label="Delete account data"
|
|
@@ -610,7 +610,7 @@ export const FormWithFileField: Story = {
|
|
|
610
610
|
<label className="block text-sm font-medium mb-1">Name</label>
|
|
611
611
|
<input
|
|
612
612
|
type="text"
|
|
613
|
-
className="w-full rounded-md border border-[var(--input)] px-3 py-2"
|
|
613
|
+
className="w-full rounded-md border border-[var(--input-border)] px-3 py-2"
|
|
614
614
|
placeholder="Your name"
|
|
615
615
|
/>
|
|
616
616
|
</div>
|
|
@@ -612,6 +612,10 @@ export const StorageUsage: Story = {
|
|
|
612
612
|
};
|
|
613
613
|
|
|
614
614
|
export const MultipleProgress: Story = {
|
|
615
|
+
args: {
|
|
616
|
+
size: "lg"
|
|
617
|
+
},
|
|
618
|
+
|
|
615
619
|
render: () => (
|
|
616
620
|
<div className="w-[400px] space-y-4">
|
|
617
621
|
<Progress
|
|
@@ -637,13 +641,14 @@ export const MultipleProgress: Story = {
|
|
|
637
641
|
/>
|
|
638
642
|
</div>
|
|
639
643
|
),
|
|
644
|
+
|
|
640
645
|
parameters: {
|
|
641
646
|
docs: {
|
|
642
647
|
description: {
|
|
643
648
|
story: 'Multiple progress bars showing task list with different states.',
|
|
644
649
|
},
|
|
645
650
|
},
|
|
646
|
-
}
|
|
651
|
+
}
|
|
647
652
|
};
|
|
648
653
|
|
|
649
654
|
export const LoadingData: Story = {
|
|
@@ -654,8 +654,8 @@ export const SurveyQuestion: Story = {
|
|
|
654
654
|
|
|
655
655
|
export const DangerZone: Story = {
|
|
656
656
|
render: () => (
|
|
657
|
-
<div className="w-96 rounded-lg border border-[var(--destructive)] bg-[var(--background)] p-6">
|
|
658
|
-
<h3 className="mb-4 text-lg font-semibold text-[var(--destructive)]">Danger Zone</h3>
|
|
657
|
+
<div className="w-96 rounded-lg border border-[var(--destructive-background)] bg-[var(--background)] p-6">
|
|
658
|
+
<h3 className="mb-4 text-lg font-semibold text-[var(--destructive-background)]">Danger Zone</h3>
|
|
659
659
|
<RadioGroup
|
|
660
660
|
variant="destructive"
|
|
661
661
|
label="Delete your account?"
|
|
@@ -24,6 +24,11 @@ const meta = {
|
|
|
24
24
|
},
|
|
25
25
|
tags: ['autodocs'],
|
|
26
26
|
argTypes: {
|
|
27
|
+
variant: {
|
|
28
|
+
control: 'select',
|
|
29
|
+
options: ['default', 'block'],
|
|
30
|
+
description: 'Visual variant: underline (default) or block/pill',
|
|
31
|
+
},
|
|
27
32
|
orientation: {
|
|
28
33
|
control: 'select',
|
|
29
34
|
options: ['horizontal', 'vertical'],
|
|
@@ -87,6 +92,45 @@ export const Default: Story = {
|
|
|
87
92
|
),
|
|
88
93
|
};
|
|
89
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Block: Pill/card-style variant with accent background
|
|
97
|
+
*/
|
|
98
|
+
export const Block: Story = {
|
|
99
|
+
render: () => (
|
|
100
|
+
<Tabs variant="block" defaultSelectedKey="account" className="w-[400px]">
|
|
101
|
+
<TabList aria-label="Account settings">
|
|
102
|
+
<Tab id="account">Account</Tab>
|
|
103
|
+
<Tab id="password">Password</Tab>
|
|
104
|
+
<Tab id="settings">Settings</Tab>
|
|
105
|
+
</TabList>
|
|
106
|
+
<TabPanel id="account">
|
|
107
|
+
<div className="p-4">
|
|
108
|
+
<h3 className="text-lg font-semibold mb-2">Account Information</h3>
|
|
109
|
+
<p className="text-sm text-[var(--muted-foreground)]">
|
|
110
|
+
Manage your account details and preferences.
|
|
111
|
+
</p>
|
|
112
|
+
</div>
|
|
113
|
+
</TabPanel>
|
|
114
|
+
<TabPanel id="password">
|
|
115
|
+
<div className="p-4">
|
|
116
|
+
<h3 className="text-lg font-semibold mb-2">Password Settings</h3>
|
|
117
|
+
<p className="text-sm text-[var(--muted-foreground)]">
|
|
118
|
+
Update your password and security settings.
|
|
119
|
+
</p>
|
|
120
|
+
</div>
|
|
121
|
+
</TabPanel>
|
|
122
|
+
<TabPanel id="settings">
|
|
123
|
+
<div className="p-4">
|
|
124
|
+
<h3 className="text-lg font-semibold mb-2">General Settings</h3>
|
|
125
|
+
<p className="text-sm text-[var(--muted-foreground)]">
|
|
126
|
+
Configure application preferences.
|
|
127
|
+
</p>
|
|
128
|
+
</div>
|
|
129
|
+
</TabPanel>
|
|
130
|
+
</Tabs>
|
|
131
|
+
),
|
|
132
|
+
};
|
|
133
|
+
|
|
90
134
|
// ============================================================================
|
|
91
135
|
// Orientation Stories
|
|
92
136
|
// ============================================================================
|
|
@@ -305,7 +349,7 @@ export const IconsAndBadges: Story = {
|
|
|
305
349
|
<Mail className="h-4 w-4" aria-hidden="true" />
|
|
306
350
|
Messages
|
|
307
351
|
<span
|
|
308
|
-
className="inline-flex items-center justify-center px-2 py-0.5 text-xs font-medium rounded-full bg-[var(--destructive)] text-[var(--destructive-foreground)]"
|
|
352
|
+
className="inline-flex items-center justify-center px-2 py-0.5 text-xs font-medium rounded-full bg-[var(--destructive-background)] text-[var(--destructive-foreground)]"
|
|
309
353
|
aria-label="5 unread"
|
|
310
354
|
>
|
|
311
355
|
5
|