@mks2508/mks-ui 0.5.1 → 0.5.4

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.
Files changed (72) hide show
  1. package/dist/react-ui/index.js +8 -1
  2. package/dist/react-ui/primitives/index.js +5 -0
  3. package/dist/react-ui/primitives/waapi/Gooey/Gooey.types.d.ts +103 -0
  4. package/dist/react-ui/primitives/waapi/Gooey/Gooey.types.d.ts.map +1 -0
  5. package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.d.ts +10 -0
  6. package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.d.ts.map +1 -0
  7. package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.js +59 -0
  8. package/dist/react-ui/primitives/waapi/Gooey/GooeyFilter.d.ts +7 -0
  9. package/dist/react-ui/primitives/waapi/Gooey/GooeyFilter.d.ts.map +1 -0
  10. package/dist/react-ui/primitives/waapi/Gooey/GooeyFilter.js +78 -0
  11. package/dist/react-ui/primitives/waapi/Gooey/MorphPath.d.ts +7 -0
  12. package/dist/react-ui/primitives/waapi/Gooey/MorphPath.d.ts.map +1 -0
  13. package/dist/react-ui/primitives/waapi/Gooey/MorphPath.js +51 -0
  14. package/dist/react-ui/primitives/waapi/Gooey/gooey-utils.d.ts +87 -0
  15. package/dist/react-ui/primitives/waapi/Gooey/gooey-utils.d.ts.map +1 -0
  16. package/dist/react-ui/primitives/waapi/Gooey/gooey-utils.js +177 -0
  17. package/dist/react-ui/primitives/waapi/Gooey/index.d.ts +28 -0
  18. package/dist/react-ui/primitives/waapi/Gooey/index.d.ts.map +1 -0
  19. package/dist/react-ui/primitives/waapi/Gooey/index.js +5 -0
  20. package/dist/react-ui/primitives/waapi/Gooey/useMorphPath.d.ts +7 -0
  21. package/dist/react-ui/primitives/waapi/Gooey/useMorphPath.d.ts.map +1 -0
  22. package/dist/react-ui/primitives/waapi/Gooey/useMorphPath.js +47 -0
  23. package/dist/react-ui/primitives/waapi/index.d.ts +2 -0
  24. package/dist/react-ui/primitives/waapi/index.d.ts.map +1 -1
  25. package/dist/react-ui/primitives/waapi/index.js +6 -0
  26. package/dist/react-ui/ui/DataCard/DataCard.styles.d.ts +26 -16
  27. package/dist/react-ui/ui/DataCard/DataCard.styles.d.ts.map +1 -1
  28. package/dist/react-ui/ui/DataCard/DataCard.styles.js +36 -74
  29. package/dist/react-ui/ui/DataCard/DataCard.types.d.ts +50 -70
  30. package/dist/react-ui/ui/DataCard/DataCard.types.d.ts.map +1 -1
  31. package/dist/react-ui/ui/DataCard/index.d.ts +24 -93
  32. package/dist/react-ui/ui/DataCard/index.d.ts.map +1 -1
  33. package/dist/react-ui/ui/DataCard/index.js +76 -118
  34. package/dist/react-ui/ui/DynamicToggle/DynamicToggle-Cm6-VceQ.css +304 -0
  35. package/dist/react-ui/ui/DynamicToggle/DynamicToggle.css +303 -0
  36. package/dist/react-ui/ui/DynamicToggle/DynamicToggle.js +0 -0
  37. package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.d.ts +35 -0
  38. package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.d.ts.map +1 -0
  39. package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.js +67 -0
  40. package/dist/react-ui/ui/DynamicToggle/DynamicToggle.types.d.ts +138 -0
  41. package/dist/react-ui/ui/DynamicToggle/DynamicToggle.types.d.ts.map +1 -0
  42. package/dist/react-ui/ui/DynamicToggle/index.d.ts +31 -0
  43. package/dist/react-ui/ui/DynamicToggle/index.d.ts.map +1 -0
  44. package/dist/react-ui/ui/DynamicToggle/index.js +188 -0
  45. package/dist/react-ui/ui/Switch/index.js +1 -1
  46. package/dist/react-ui/ui/index.d.ts +1 -0
  47. package/dist/react-ui/ui/index.d.ts.map +1 -1
  48. package/dist/react-ui/ui/index.js +2 -0
  49. package/package.json +2 -2
  50. package/src/css.d.ts +1 -0
  51. package/src/react-ui/primitives/waapi/Gooey/Gooey.types.ts +123 -0
  52. package/src/react-ui/primitives/waapi/Gooey/GooeyCanvas.tsx +80 -0
  53. package/src/react-ui/primitives/waapi/Gooey/GooeyFilter.tsx +77 -0
  54. package/src/react-ui/primitives/waapi/Gooey/MorphPath.tsx +58 -0
  55. package/src/react-ui/primitives/waapi/Gooey/gooey-utils.ts +244 -0
  56. package/src/react-ui/primitives/waapi/Gooey/index.ts +50 -0
  57. package/src/react-ui/primitives/waapi/Gooey/useMorphPath.ts +48 -0
  58. package/src/react-ui/primitives/waapi/index.ts +23 -0
  59. package/src/react-ui/ui/DataCard/DataCard.styles.ts +45 -101
  60. package/src/react-ui/ui/DataCard/DataCard.types.ts +52 -73
  61. package/src/react-ui/ui/DataCard/index.tsx +118 -184
  62. package/src/react-ui/ui/DynamicToggle/DynamicToggle.css +303 -0
  63. package/src/react-ui/ui/DynamicToggle/DynamicToggle.styles.ts +85 -0
  64. package/src/react-ui/ui/DynamicToggle/DynamicToggle.types.ts +174 -0
  65. package/src/react-ui/ui/DynamicToggle/index.tsx +294 -0
  66. package/src/react-ui/ui/DynamicToggle/prototype-v7.html +615 -0
  67. package/src/react-ui/ui/DynamicToggle/prototype.html +419 -0
  68. package/src/react-ui/ui/Switch/index.tsx +1 -1
  69. package/src/react-ui/ui/index.ts +3 -0
  70. /package/dist/react-ui/blocks/Terminal/panel/{terminal-filter-dropdown.module-CNVWCefU.css → terminal-filter-dropdown.module-C6oDcFBS.css} +0 -0
  71. /package/dist/react-ui/blocks/Terminal/panel/{terminal-session-tabs.module-cmyJ11jP.css → terminal-session-tabs.module-D_-sgyza.css} +0 -0
  72. /package/dist/react-ui/components/MorphingPopover/{morphing-popover.module-BycNI8nU.css → morphing-popover.module-B1ftlaYj.css} +0 -0
@@ -0,0 +1,67 @@
1
+ import { cva } from "class-variance-authority";
2
+
3
+ //#region src/react-ui/ui/DynamicToggle/DynamicToggle.styles.ts
4
+ /**
5
+ * DynamicToggle style slots + CVA variants.
6
+ *
7
+ * Layout via Tailwind. State animations via CSS file (`:has()`, `clip-path`).
8
+ * Shape propagated to indicators via `--dt-radius` CSS variable.
9
+ *
10
+ * @module @mks2508/mks-ui/react/ui/DynamicToggle
11
+ */
12
+ /**
13
+ * Default styles for each DynamicToggle slot.
14
+ *
15
+ * Width is set by size variants — required because indicator uses `width: 50%`
16
+ * and clip-path uses container query units. Override: `slots={{ root: 'w-80' }}`.
17
+ */
18
+ const dynamicToggleStyles = {
19
+ root: "relative border p-[2px] select-none",
20
+ track: "relative grid grid-cols-[repeat(4,1fr)] place-items-center w-full h-full",
21
+ option: "inline-grid place-items-center cursor-pointer font-medium z-[2] h-full w-full whitespace-nowrap",
22
+ indicator: "absolute w-1/2 left-0 top-0 bottom-0 bg-foreground rounded-[var(--dt-radius,9999px)] pointer-events-none z-0",
23
+ group: "col-span-2 relative w-full h-full grid grid-cols-2",
24
+ groupIndicator: "absolute left-1/2 top-0 bottom-0 w-1/2 bg-foreground rounded-[var(--dt-radius,9999px)] pointer-events-none z-0",
25
+ groupLabel: [
26
+ "absolute",
27
+ "flex items-center justify-center",
28
+ "text-muted-foreground font-medium whitespace-nowrap",
29
+ "pointer-events-none"
30
+ ].join(" ")
31
+ };
32
+ /**
33
+ * CVA variants for DynamicToggle root.
34
+ *
35
+ * @example
36
+ * ```tsx
37
+ * <DynamicToggle size="sm" variant="outline" shape="rounded">
38
+ * ```
39
+ */
40
+ const dynamicToggleVariants = cva(dynamicToggleStyles.root, {
41
+ variants: {
42
+ variant: {
43
+ default: "bg-card border-border shadow-sm",
44
+ ghost: "bg-transparent border-transparent",
45
+ muted: "bg-muted border-muted",
46
+ outline: "bg-transparent border-border"
47
+ },
48
+ size: {
49
+ sm: "h-[30px] w-[210px] text-[10px] [--dt-h:30px]",
50
+ default: "h-[38px] w-[260px] text-xs [--dt-h:38px]",
51
+ lg: "h-[44px] w-80 text-sm [--dt-h:44px]"
52
+ },
53
+ shape: {
54
+ pill: "rounded-full [--dt-radius:9999px]",
55
+ rounded: "rounded-xl [--dt-radius:0.75rem]",
56
+ square: "rounded-md [--dt-radius:0.375rem]"
57
+ }
58
+ },
59
+ defaultVariants: {
60
+ variant: "default",
61
+ size: "default",
62
+ shape: "pill"
63
+ }
64
+ });
65
+
66
+ //#endregion
67
+ export { dynamicToggleStyles, dynamicToggleVariants };
@@ -0,0 +1,138 @@
1
+ /**
2
+ * DynamicToggle type definitions.
3
+ *
4
+ * CSS-animated toggle where one option expands into sub-options.
5
+ * Uses hidden radios + `:has(:checked)` for zero-JS animation.
6
+ * Optional gooey morph via `GooeyCanvas` or `MorphPath` primitives.
7
+ *
8
+ * @module @mks2508/mks-ui/react/ui/DynamicToggle
9
+ */
10
+ import type { SlotOverrides, IBaseConfig } from '../../../core/types';
11
+ import type { DynamicToggleSlot, DynamicToggleVariantProps } from './DynamicToggle.styles';
12
+ /** How the group appears when collapsed (standalone option active). */
13
+ export type DynamicToggleCollapsedMode = 'title' | 'opts' | 'title-opts';
14
+ /** Morph technique for the pill↔groupLabel junction. */
15
+ export type DynamicToggleMorphMode = 'none' | 'filter' | 'path';
16
+ /**
17
+ * Configuration for DynamicToggle animation behavior.
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * <DynamicToggle config={{ morphMode: 'filter', duration: 0.3 }}>
22
+ * ...
23
+ * </DynamicToggle>
24
+ * ```
25
+ */
26
+ export interface IDynamicToggleConfig extends IBaseConfig {
27
+ /** CSS transition duration in seconds (default: 0.22) */
28
+ duration?: number;
29
+ /** Label animation style (default: 'morph') */
30
+ labelAnimation?: 'morph' | 'float' | 'none';
31
+ /** Gooey morph mode for the pill↔groupLabel junction (default: 'none') */
32
+ morphMode?: DynamicToggleMorphMode;
33
+ }
34
+ /**
35
+ * Context shared between DynamicToggle root and its children.
36
+ */
37
+ export type DynamicToggleContextType = {
38
+ /** Current selected value */
39
+ value: string;
40
+ /** Update selected value */
41
+ setValue: (value: string) => void;
42
+ /** Auto-generated radio group name */
43
+ groupName: string;
44
+ /** Whether a group child is active */
45
+ groupActive: boolean;
46
+ /** Whether the toggle is disabled */
47
+ disabled: boolean;
48
+ /** Register group info (called by DynamicToggleGroup on mount) */
49
+ registerGroup: (label: string, values: string[], position: 'top' | 'bottom' | 'hidden', collapsedMode: DynamicToggleCollapsedMode) => void;
50
+ };
51
+ /**
52
+ * Props for the DynamicToggle root container.
53
+ *
54
+ * Supports exactly one `DynamicToggleOption` + one `DynamicToggleGroup`.
55
+ * The group expands into sub-options when one of its children is active.
56
+ *
57
+ * @example
58
+ * ```tsx
59
+ * <DynamicToggle
60
+ * value="tree" onValueChange={setVal}
61
+ * size="sm" config={{ morphMode: 'filter' }}
62
+ * >
63
+ * <DynamicToggleOption value="tree">Tree</DynamicToggleOption>
64
+ * <DynamicToggleGroup label="Changes" collapsedMode="title">
65
+ * <DynamicToggleOption value="flat">Flat</DynamicToggleOption>
66
+ * <DynamicToggleOption value="grouped">Grouped</DynamicToggleOption>
67
+ * </DynamicToggleGroup>
68
+ * </DynamicToggle>
69
+ * ```
70
+ */
71
+ export interface IDynamicToggleProps extends DynamicToggleVariantProps {
72
+ /** Controlled value */
73
+ value?: string;
74
+ /** Uncontrolled default value */
75
+ defaultValue?: string;
76
+ /** Change callback */
77
+ onValueChange?: (value: string) => void;
78
+ /** Disable the entire toggle */
79
+ disabled?: boolean;
80
+ /** Slot class overrides */
81
+ slots?: SlotOverrides<DynamicToggleSlot>;
82
+ /** Animation/behavior configuration */
83
+ config?: IDynamicToggleConfig;
84
+ /** Accessible label for the radio group */
85
+ 'aria-label'?: string;
86
+ /** Additional class for the root */
87
+ className?: string;
88
+ /** DynamicToggleOption and DynamicToggleGroup children */
89
+ children: React.ReactNode;
90
+ }
91
+ /**
92
+ * Props for a single toggle option (top-level or inside a group).
93
+ *
94
+ * @example
95
+ * ```tsx
96
+ * <DynamicToggleOption value="tree">Tree</DynamicToggleOption>
97
+ * ```
98
+ */
99
+ export interface IDynamicToggleOptionProps {
100
+ /** Value this option represents */
101
+ value: string;
102
+ /** Label content */
103
+ children: React.ReactNode;
104
+ /** Additional class */
105
+ className?: string;
106
+ }
107
+ /**
108
+ * Props for an expandable group of options.
109
+ *
110
+ * When none of the group's options are active, shows collapsed content
111
+ * based on `collapsedMode`:
112
+ * - `'title'` — only the group label
113
+ * - `'opts'` — only the combined sub-option text ("Solo · Team")
114
+ * - `'title-opts'` — WIP: currently falls back to 'title' behavior
115
+ *
116
+ * When one is active, expands with a clip-path reveal animation.
117
+ *
118
+ * @example
119
+ * ```tsx
120
+ * <DynamicToggleGroup label="Premium" collapsedMode="title">
121
+ * <DynamicToggleOption value="solo">Solo</DynamicToggleOption>
122
+ * <DynamicToggleOption value="team">Team</DynamicToggleOption>
123
+ * </DynamicToggleGroup>
124
+ * ```
125
+ */
126
+ export interface IDynamicToggleGroupProps {
127
+ /** Label shown as group title / group label text */
128
+ label: string;
129
+ /** Group label position relative to the pill (default: 'top') */
130
+ labelPosition?: 'top' | 'bottom' | 'hidden';
131
+ /** How the group appears when collapsed (default: 'title') */
132
+ collapsedMode?: DynamicToggleCollapsedMode;
133
+ /** Exactly 2 DynamicToggleOption children */
134
+ children: React.ReactNode;
135
+ /** Additional class */
136
+ className?: string;
137
+ }
138
+ //# sourceMappingURL=DynamicToggle.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DynamicToggle.types.d.ts","sourceRoot":"","sources":["../../../../src/react-ui/ui/DynamicToggle/DynamicToggle.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAM3F,uEAAuE;AACvE,MAAM,MAAM,0BAA0B,GAAG,OAAO,GAAG,MAAM,GAAG,YAAY,CAAC;AAEzE,wDAAwD;AACxD,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AAMhE;;;;;;;;;GASG;AACH,MAAM,WAAW,oBAAqB,SAAQ,WAAW;IACvD,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;IAC5C,0EAA0E;IAC1E,SAAS,CAAC,EAAE,sBAAsB,CAAC;CACpC;AAMD;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,4BAA4B;IAC5B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,WAAW,EAAE,OAAO,CAAC;IACrB,qCAAqC;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,kEAAkE;IAClE,aAAa,EAAE,CACb,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EAAE,EAChB,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,EACrC,aAAa,EAAE,0BAA0B,KACtC,IAAI,CAAC;CACX,CAAC;AAMF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,mBAAoB,SAAQ,yBAAyB;IACpE,uBAAuB;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sBAAsB;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,gCAAgC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IACzC,uCAAuC;IACvC,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAMD;;;;;;;GAOG;AACH,MAAM,WAAW,yBAAyB;IACxC,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,oBAAoB;IACpB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,wBAAwB;IACvC,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,aAAa,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC5C,8DAA8D;IAC9D,aAAa,CAAC,EAAE,0BAA0B,CAAC;IAC3C,6CAA6C;IAC7C,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
@@ -0,0 +1,31 @@
1
+ import './DynamicToggle.css';
2
+ import { dynamicToggleVariants } from './DynamicToggle.styles';
3
+ import type { DynamicToggleContextType, IDynamicToggleProps, IDynamicToggleOptionProps, IDynamicToggleGroupProps } from './DynamicToggle.types';
4
+ declare const useDynamicToggle: () => DynamicToggleContextType;
5
+ /**
6
+ * Root container — pill-shaped toggle with expanding sub-options and group label.
7
+ */
8
+ declare function DynamicToggle({ variant, size, shape, slots, config, disabled, className, children, 'aria-label': ariaLabel, ...props }: IDynamicToggleProps): import("react/jsx-runtime").JSX.Element;
9
+ declare namespace DynamicToggle {
10
+ var displayName: string;
11
+ }
12
+ /**
13
+ * A single toggle option — hidden radio + visible label.
14
+ */
15
+ declare function DynamicToggleOption({ value, children, className }: IDynamicToggleOptionProps): import("react/jsx-runtime").JSX.Element;
16
+ declare namespace DynamicToggleOption {
17
+ var displayName: string;
18
+ }
19
+ /**
20
+ * Expandable group — registers with root on mount, renders sub-options.
21
+ * The group label is rendered by the root based on registered info.
22
+ */
23
+ declare function DynamicToggleGroup({ label, labelPosition, collapsedMode, children, className, }: IDynamicToggleGroupProps): import("react/jsx-runtime").JSX.Element;
24
+ declare namespace DynamicToggleGroup {
25
+ var displayName: string;
26
+ }
27
+ export { DynamicToggle, DynamicToggleOption, DynamicToggleGroup, useDynamicToggle, dynamicToggleVariants, };
28
+ export type { IDynamicToggleProps, IDynamicToggleOptionProps, IDynamicToggleGroupProps, IDynamicToggleConfig, DynamicToggleContextType, DynamicToggleCollapsedMode, DynamicToggleMorphMode, } from './DynamicToggle.types';
29
+ export type { DynamicToggleSlot, DynamicToggleVariantProps } from './DynamicToggle.styles';
30
+ export { dynamicToggleStyles } from './DynamicToggle.styles';
31
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/react-ui/ui/DynamicToggle/index.tsx"],"names":[],"mappings":"AA8BA,OAAO,qBAAqB,CAAC;AAC7B,OAAO,EAAuB,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AACpF,OAAO,KAAK,EACV,wBAAwB,EAExB,mBAAmB,EACnB,yBAAyB,EACzB,wBAAwB,EACzB,MAAM,uBAAuB,CAAC;AAM/B,QAAA,MAA8B,gBAAgB,gCACsB,CAAC;AAuBrE;;GAEG;AACH,iBAAS,aAAa,CAAC,EACrB,OAAO,EACP,IAAI,EACJ,KAAK,EACL,KAAK,EACL,MAAM,EACN,QAAgB,EAChB,SAAS,EACT,QAAQ,EACR,YAAY,EAAE,SAAS,EACvB,GAAG,KAAK,EACT,EAAE,mBAAmB,2CAuFrB;kBAlGQ,aAAa;;;AAwGtB;;GAEG;AACH,iBAAS,mBAAmB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,yBAAyB,2CA2BrF;kBA3BQ,mBAAmB;;;AAiC5B;;;GAGG;AACH,iBAAS,kBAAkB,CAAC,EAC1B,KAAK,EACL,aAAqB,EACrB,aAAuB,EACvB,QAAQ,EACR,SAAS,GACV,EAAE,wBAAwB,2CA0C1B;kBAhDQ,kBAAkB;;;AA2D3B,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,GACtB,CAAC;AAEF,YAAY,EACV,mBAAmB,EACnB,yBAAyB,EACzB,wBAAwB,EACxB,oBAAoB,EACpB,wBAAwB,EACxB,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAC3F,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,188 @@
1
+ 'use client';
2
+
3
+ import { cn } from "../../lib/utils.js";
4
+ import { GooeyCanvas } from "../../primitives/waapi/Gooey/GooeyCanvas.js";
5
+ import { getStrictContext } from "../../lib/get-strict-context.js";
6
+ import { useControlledState } from "../../hooks/State/UseControlledState.js";
7
+ import "./DynamicToggle.js";
8
+ import { dynamicToggleStyles, dynamicToggleVariants } from "./DynamicToggle.styles.js";
9
+ import * as React$1 from "react";
10
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
+
12
+ //#region src/react-ui/ui/DynamicToggle/index.tsx
13
+ /**
14
+ * DynamicToggle — CSS-animated toggle with expanding sub-options and group label.
15
+ *
16
+ * Pure CSS animation via `:has(:checked)` on hidden radio inputs.
17
+ * When the group is active, a group label grows out of the pill.
18
+ * Optional gooey morph via `config.morphMode` for organic junction.
19
+ *
20
+ * Supports exactly 1 `DynamicToggleOption` + 1 `DynamicToggleGroup` (with 2 sub-options).
21
+ *
22
+ * @module @mks2508/mks-ui/react/ui/DynamicToggle
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * <DynamicToggle value="tree" onValueChange={setVal} size="sm" shape="pill">
27
+ * <DynamicToggleOption value="tree">Tree</DynamicToggleOption>
28
+ * <DynamicToggleGroup label="Changes" collapsedMode="title" labelPosition="top">
29
+ * <DynamicToggleOption value="flat">Flat</DynamicToggleOption>
30
+ * <DynamicToggleOption value="grouped">Grouped</DynamicToggleOption>
31
+ * </DynamicToggleGroup>
32
+ * </DynamicToggle>
33
+ * ```
34
+ */
35
+ const [DynamicToggleProvider, useDynamicToggle] = getStrictContext("DynamicToggleContext");
36
+ const useIsomorphicLayoutEffect = typeof window !== "undefined" ? React$1.useLayoutEffect : React$1.useEffect;
37
+ const SIZE_HEIGHT_PX = {
38
+ sm: 30,
39
+ default: 38,
40
+ lg: 44
41
+ };
42
+ /**
43
+ * Root container — pill-shaped toggle with expanding sub-options and group label.
44
+ */
45
+ function DynamicToggle({ variant, size, shape, slots, config, disabled = false, className, children, "aria-label": ariaLabel, ...props }) {
46
+ const [value, setValue] = useControlledState({
47
+ value: props.value,
48
+ defaultValue: props.defaultValue ?? "",
49
+ onChange: props.onValueChange
50
+ });
51
+ const groupName = React$1.useId();
52
+ const [groupLabel, setGroupLabel] = React$1.useState("");
53
+ const [groupValues, setGroupValues] = React$1.useState([]);
54
+ const [groupPosition, setGroupPosition] = React$1.useState("top");
55
+ const [groupCollapsedMode, setGroupCollapsedMode] = React$1.useState("title");
56
+ const registerGroup = React$1.useCallback((label, values, position, collapsedMode) => {
57
+ setGroupLabel(label);
58
+ setGroupValues(values);
59
+ setGroupPosition(position);
60
+ setGroupCollapsedMode(collapsedMode);
61
+ }, []);
62
+ const groupActive = groupValues.includes(value);
63
+ const morphMode = config?.morphMode ?? "none";
64
+ const resolvedVariant = variant ?? "default";
65
+ const effectiveMorphMode = resolvedVariant === "ghost" || resolvedVariant === "outline" ? "none" : morphMode;
66
+ const showGroupLabel = (config?.labelAnimation ?? "morph") !== "none" && groupPosition !== "hidden" && groupLabel;
67
+ const heightPx = SIZE_HEIGHT_PX[size ?? "default"] ?? 32;
68
+ const style = config?.duration ? { "--dt-dur": `${config.duration}s` } : void 0;
69
+ const groupLabelElement = showGroupLabel ? /* @__PURE__ */ jsx("div", {
70
+ "data-slot": "dt-group-label",
71
+ "data-position": groupPosition,
72
+ className: cn(dynamicToggleStyles.groupLabel, slots?.groupLabel),
73
+ children: /* @__PURE__ */ jsx("span", { children: groupLabel || "\xA0" })
74
+ }) : null;
75
+ return /* @__PURE__ */ jsx(DynamicToggleProvider, {
76
+ value: {
77
+ value,
78
+ setValue,
79
+ groupName,
80
+ groupActive,
81
+ disabled,
82
+ registerGroup
83
+ },
84
+ children: /* @__PURE__ */ jsxs("div", {
85
+ "data-slot": "dt-root",
86
+ "data-morph": effectiveMorphMode !== "none" ? effectiveMorphMode : void 0,
87
+ "data-group-active": groupActive || void 0,
88
+ "data-disabled": disabled || void 0,
89
+ role: "radiogroup",
90
+ "aria-label": ariaLabel,
91
+ style,
92
+ className: cn(dynamicToggleVariants({
93
+ variant,
94
+ size,
95
+ shape
96
+ }), slots?.root, className),
97
+ children: [
98
+ effectiveMorphMode === "filter" && /* @__PURE__ */ jsxs(GooeyCanvas, {
99
+ height: heightPx,
100
+ children: [/* @__PURE__ */ jsx("div", { className: "absolute inset-0 rounded-[inherit] bg-card" }), groupLabelElement]
101
+ }),
102
+ effectiveMorphMode === "path" && groupLabelElement,
103
+ /* @__PURE__ */ jsxs("div", {
104
+ "data-slot": "dt-track",
105
+ className: cn(dynamicToggleStyles.track, slots?.track),
106
+ children: [/* @__PURE__ */ jsx("div", {
107
+ "data-slot": "dt-indicator",
108
+ className: cn(dynamicToggleStyles.indicator, slots?.indicator)
109
+ }), children]
110
+ })
111
+ ]
112
+ })
113
+ });
114
+ }
115
+ /**
116
+ * A single toggle option — hidden radio + visible label.
117
+ */
118
+ function DynamicToggleOption({ value, children, className }) {
119
+ const ctx = useDynamicToggle();
120
+ const id = React$1.useId();
121
+ const isActive = ctx.value === value;
122
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("label", {
123
+ htmlFor: id,
124
+ "data-slot": "dt-option",
125
+ "data-active": isActive || void 0,
126
+ className: cn(dynamicToggleStyles.option, className),
127
+ children: /* @__PURE__ */ jsx("span", { children })
128
+ }), /* @__PURE__ */ jsx("input", {
129
+ className: "sr-only",
130
+ type: "radio",
131
+ name: ctx.groupName,
132
+ id,
133
+ value,
134
+ checked: isActive,
135
+ disabled: ctx.disabled,
136
+ onChange: () => ctx.setValue(value)
137
+ })] });
138
+ }
139
+ /**
140
+ * Expandable group — registers with root on mount, renders sub-options.
141
+ * The group label is rendered by the root based on registered info.
142
+ */
143
+ function DynamicToggleGroup({ label, labelPosition = "top", collapsedMode = "title", children, className }) {
144
+ const ctx = useDynamicToggle();
145
+ const optsText = React$1.useMemo(() => {
146
+ const labels = [];
147
+ React$1.Children.forEach(children, (child) => {
148
+ if (React$1.isValidElement(child)) {
149
+ const p = child.props;
150
+ if (p.children) labels.push(String(p.children));
151
+ }
152
+ });
153
+ return labels.join(" · ");
154
+ }, [children]);
155
+ useIsomorphicLayoutEffect(() => {
156
+ const values = [];
157
+ React$1.Children.forEach(children, (child) => {
158
+ if (React$1.isValidElement(child)) {
159
+ const p = child.props;
160
+ if (p.value) values.push(p.value);
161
+ }
162
+ });
163
+ ctx.registerGroup(label, values, labelPosition, collapsedMode);
164
+ }, [
165
+ label,
166
+ labelPosition,
167
+ collapsedMode,
168
+ children,
169
+ ctx.registerGroup
170
+ ]);
171
+ return /* @__PURE__ */ jsxs("div", {
172
+ "data-slot": "dt-group",
173
+ "data-collapsed": collapsedMode,
174
+ "data-label": label,
175
+ "data-opts": collapsedMode !== "title" ? optsText : void 0,
176
+ className: cn(dynamicToggleStyles.group, className),
177
+ children: [/* @__PURE__ */ jsx("div", {
178
+ "data-slot": "dt-group-indicator",
179
+ className: dynamicToggleStyles.groupIndicator
180
+ }), children]
181
+ });
182
+ }
183
+ DynamicToggle.displayName = "DynamicToggle";
184
+ DynamicToggleOption.displayName = "DynamicToggleOption";
185
+ DynamicToggleGroup.displayName = "DynamicToggleGroup";
186
+
187
+ //#endregion
188
+ export { DynamicToggle, DynamicToggleGroup, DynamicToggleOption, useDynamicToggle };
@@ -85,7 +85,7 @@ function Switch$1({ name, defaultChecked, checked, onCheckedChange, nativeButton
85
85
  defaultChecked,
86
86
  checked,
87
87
  onCheckedChange: setIsChecked,
88
- nativeButton,
88
+ nativeButton: nativeButton ?? true,
89
89
  disabled,
90
90
  readOnly,
91
91
  required,
@@ -30,4 +30,5 @@ export * from './Separator';
30
30
  export * from './Textarea';
31
31
  export * from './DataCard';
32
32
  export * from './TextFlow';
33
+ export * from './DynamicToggle';
33
34
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/react-ui/ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAG1B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAG3B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/react-ui/ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAG1B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAG3B,cAAc,YAAY,CAAC;AAG3B,cAAc,iBAAiB,CAAC"}
@@ -39,3 +39,5 @@ import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScro
39
39
  import { dataCardStyles, dataCardVariants } from "./DataCard/DataCard.styles.js";
40
40
  import { DataCard, DataCardActions, DataCardBracket, DataCardLabel, DataCardToggle, DataCardValue, useDataCard } from "./DataCard/index.js";
41
41
  import { TextFlow } from "./TextFlow/index.js";
42
+ import { dynamicToggleStyles, dynamicToggleVariants } from "./DynamicToggle/DynamicToggle.styles.js";
43
+ import { DynamicToggle, DynamicToggleGroup, DynamicToggleOption, useDynamicToggle } from "./DynamicToggle/index.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mks2508/mks-ui",
3
- "version": "0.5.1",
3
+ "version": "0.5.4",
4
4
  "description": "UI component library - Shadcn/Animate UI based with DevEnv components",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -49,7 +49,7 @@
49
49
  ],
50
50
  "scripts": {
51
51
  "dev": "vite",
52
- "build": "rm -rf dist && bunx rolldown --config rolldown.config.ts && bunx tsc --emitDeclarationOnly && bunx tsc-alias && cp src/index.css dist/index.css",
52
+ "build": "rm -rf dist && bunx rolldown --config rolldown.config.ts && bunx tsc --emitDeclarationOnly && bunx tsc-alias && cp src/index.css dist/index.css && mkdir -p dist/react-ui/ui/DynamicToggle && cp src/react-ui/ui/DynamicToggle/DynamicToggle.css dist/react-ui/ui/DynamicToggle/DynamicToggle.css",
53
53
  "typecheck": "bunx tsc --noEmit",
54
54
  "lint": "bunx oxlint .",
55
55
  "preview": "vite preview",
package/src/css.d.ts CHANGED
@@ -4,3 +4,4 @@ declare module '*.module.css' {
4
4
  }
5
5
 
6
6
  declare module '@xterm/xterm/css/xterm.css';
7
+ declare module '*.css';
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Gooey morphing primitive types.
3
+ *
4
+ * @module @mks2508/mks-ui/react/primitives/waapi/Gooey
5
+ */
6
+
7
+ import type { ReactNode } from 'react';
8
+
9
+ // ---------------------------------------------------------------------------
10
+ // GooeyFilter
11
+ // ---------------------------------------------------------------------------
12
+
13
+ /**
14
+ * Props for the GooeyFilter SVG filter definition.
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * <GooeyFilter id="my-goo" blur={8} />
19
+ * ```
20
+ */
21
+ export interface IGooeyFilterProps {
22
+ /** Unique filter ID — referenced via `filter: url(#id)` */
23
+ id: string;
24
+ /** Gaussian blur stdDeviation (default: 8) */
25
+ blur?: number;
26
+ /** Alpha channel multiplier in feColorMatrix (default: 20) */
27
+ alphaGain?: number;
28
+ /** Alpha channel offset in feColorMatrix (default: -10) */
29
+ alphaOffset?: number;
30
+ }
31
+
32
+ // ---------------------------------------------------------------------------
33
+ // GooeyCanvas
34
+ // ---------------------------------------------------------------------------
35
+
36
+ /**
37
+ * Props for the GooeyCanvas container.
38
+ *
39
+ * Wraps children with an SVG gooey filter. All same-colored children
40
+ * inside automatically merge visually into an organic blob.
41
+ *
42
+ * @example
43
+ * ```tsx
44
+ * <GooeyCanvas height={40}>
45
+ * <div className="bg-card rounded-full h-10 w-64" />
46
+ * <div className="bg-card absolute bottom-full w-32 h-6" />
47
+ * </GooeyCanvas>
48
+ * ```
49
+ */
50
+ export interface IGooeyCanvasProps {
51
+ /** Blur radius override. If omitted, auto-calculated from `height`. */
52
+ blur?: number;
53
+ /** Element height — used to auto-calculate blur (default: 32) */
54
+ height?: number;
55
+ /** Drop-shadow outline blur in px (default: 0.5) */
56
+ outlineBlur?: number;
57
+ /** Drop-shadow outline color (default: 'var(--border)') */
58
+ outlineColor?: string;
59
+ /** Number of stacked drop-shadows for outline thickness (default: 2) */
60
+ outlineLayers?: number;
61
+ /** Alpha gain override */
62
+ alphaGain?: number;
63
+ /** Alpha offset override */
64
+ alphaOffset?: number;
65
+ /** Extra className on the filter container */
66
+ className?: string;
67
+ /** Content to merge with the gooey filter */
68
+ children: ReactNode;
69
+ }
70
+
71
+ // ---------------------------------------------------------------------------
72
+ // MorphPath
73
+ // ---------------------------------------------------------------------------
74
+
75
+ /**
76
+ * Props for the MorphPath SVG path component.
77
+ *
78
+ * Renders a parametric `<path>` that morphs from a pill shape to a
79
+ * pill+body blob based on the `progress` value.
80
+ *
81
+ * @example
82
+ * ```tsx
83
+ * <svg>
84
+ * <MorphPath pillWidth={260} bodyWidth={180} totalHeight={60} progress={0.5} fill="var(--card)" />
85
+ * </svg>
86
+ * ```
87
+ */
88
+ export interface IMorphPathProps extends React.SVGProps<SVGPathElement> {
89
+ /** Pill width in px */
90
+ pillWidth: number;
91
+ /** Body (expanded area) width in px */
92
+ bodyWidth: number;
93
+ /** Total height (pill + body) in px */
94
+ totalHeight: number;
95
+ /** Morph progress: 0 = pill only, 1 = fully expanded */
96
+ progress: number;
97
+ /** Pill height (default: 34) */
98
+ pillHeight?: number;
99
+ /** Body expansion direction relative to pill */
100
+ direction?: 'down' | 'up';
101
+ }
102
+
103
+ // ---------------------------------------------------------------------------
104
+ // useMorphPath
105
+ // ---------------------------------------------------------------------------
106
+
107
+ /**
108
+ * Options for the useMorphPath hook.
109
+ */
110
+ export interface IUseMorphPathOptions {
111
+ /** Pill width in px */
112
+ pillWidth: number;
113
+ /** Body width in px */
114
+ bodyWidth: number;
115
+ /** Total height in px */
116
+ totalHeight: number;
117
+ /** Morph progress 0→1 */
118
+ progress: number;
119
+ /** Pill height (default: 34) */
120
+ pillHeight?: number;
121
+ /** Body direction */
122
+ direction?: 'down' | 'up';
123
+ }