@manakind/manuia-ui 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +45 -0
  3. package/dist/goal-card/goal-card.css +592 -0
  4. package/dist/goal-card/goal-card.d.ts +92 -0
  5. package/dist/goal-card/goal-card.d.ts.map +1 -0
  6. package/dist/goal-card/goal-card.js +66 -0
  7. package/dist/goal-card/goal-card.js.map +1 -0
  8. package/dist/goal-card/index.d.ts +3 -0
  9. package/dist/goal-card/index.d.ts.map +1 -0
  10. package/dist/goal-card/index.js +2 -0
  11. package/dist/goal-card/index.js.map +1 -0
  12. package/dist/goal-categories/goal-categories.css +51 -0
  13. package/dist/goal-categories/goal-categories.d.ts +55 -0
  14. package/dist/goal-categories/goal-categories.d.ts.map +1 -0
  15. package/dist/goal-categories/goal-categories.js +103 -0
  16. package/dist/goal-categories/goal-categories.js.map +1 -0
  17. package/dist/goal-categories/index.d.ts +3 -0
  18. package/dist/goal-categories/index.d.ts.map +1 -0
  19. package/dist/goal-categories/index.js +2 -0
  20. package/dist/goal-categories/index.js.map +1 -0
  21. package/dist/goal-tab-trigger/goal-tab-trigger.css +10 -0
  22. package/dist/goal-tab-trigger/goal-tab-trigger.d.ts +11 -0
  23. package/dist/goal-tab-trigger/goal-tab-trigger.d.ts.map +1 -0
  24. package/dist/goal-tab-trigger/goal-tab-trigger.js +34 -0
  25. package/dist/goal-tab-trigger/goal-tab-trigger.js.map +1 -0
  26. package/dist/goal-tab-trigger/index.d.ts +3 -0
  27. package/dist/goal-tab-trigger/index.d.ts.map +1 -0
  28. package/dist/goal-tab-trigger/index.js +2 -0
  29. package/dist/goal-tab-trigger/index.js.map +1 -0
  30. package/dist/index.d.ts +15 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +15 -0
  33. package/dist/index.js.map +1 -0
  34. package/package.json +75 -0
@@ -0,0 +1,92 @@
1
+ import { type IconSource } from '@manakind/ui-core';
2
+ import { type GoalCategory } from '../goal-categories';
3
+ import './goal-card.css';
4
+ /** Manuia's goal timeframes, longest horizon first. */
5
+ export type GoalType = '5 Year' | '1 Year' | 'Quarterly' | 'Monthly' | 'Weekly';
6
+ export type GoalStatus = 'Not Started' | 'In Progress' | 'Completed';
7
+ export interface GoalMilestone {
8
+ id: string;
9
+ title: string;
10
+ completed: boolean;
11
+ }
12
+ export interface GoalCardProps {
13
+ /** Goal title. Rendered as the card's heading. */
14
+ title: string;
15
+ /** Optional supporting copy. */
16
+ description?: string;
17
+ /** Timeframe. Drives the card's visual tier. */
18
+ type: GoalType;
19
+ /** Progress status, shown as a badge. */
20
+ status: GoalStatus;
21
+ /**
22
+ * Glyph for this card's status, supplied by the product so this package
23
+ * never imports an icon set — same contract as `typeIcon`.
24
+ *
25
+ * Strongly recommended. The status badge collapses to the glyph alone on a
26
+ * narrow card, and without one it collapses to a bare colour chip, which
27
+ * says nothing to anyone who cannot separate the tints. Pass a glyph whose
28
+ * outline differs per status, not just its hue.
29
+ */
30
+ statusIcon?: IconSource;
31
+ /** Categories this goal belongs to. */
32
+ categories?: GoalCategory[];
33
+ /** How many categories to show before collapsing into `+N more`. */
34
+ maxVisibleCategories?: number;
35
+ /** Milestones, rendered as a progress bar plus a checklist. */
36
+ milestones?: GoalMilestone[];
37
+ /** Pre-formatted target date. Formatting is the caller's job — this package takes no date dependency. */
38
+ targetDate?: string;
39
+ /**
40
+ * Icon shown beside the timeframe badge.
41
+ *
42
+ * Supplied by the product so this package never imports an icon set. The
43
+ * Humanity Plus apps pass a Lineicons Pro component here.
44
+ */
45
+ typeIcon?: IconSource;
46
+ /** Glyph for a completed milestone. Falls back to a filled dot. */
47
+ milestoneIcon?: IconSource;
48
+ /**
49
+ * Emblem shown on the higher tiers — the product uses a crown for 5 Year,
50
+ * a shield for 1 Year, and a compass for Quarterly.
51
+ *
52
+ * Purely decorative: it is `aria-hidden`, because the timeframe is already
53
+ * announced as text beside it. Monthly and Weekly carry no emblem, so pass
54
+ * nothing for those.
55
+ */
56
+ emblemIcon?: IconSource;
57
+ /**
58
+ * Heading level for the title. Defaults to `h3`.
59
+ *
60
+ * A grid of these usually sits under a section heading, so `h3` is right;
61
+ * override it if the surrounding outline differs.
62
+ */
63
+ titleAs?: 'h2' | 'h3' | 'h4';
64
+ /** Extra class names. */
65
+ className?: string;
66
+ }
67
+ /**
68
+ * A Manuia goal, rendered as a card.
69
+ *
70
+ * Composes `ui-core`'s `Card`, `Badge`, and `Progress` with Manuia's own
71
+ * concepts — timeframes, categories, milestones — which is exactly why it
72
+ * lives in the product package rather than in `ui-core`.
73
+ *
74
+ * Longer horizons are given more visual weight ("prestige tiers"). That is a
75
+ * deliberate product signal, not decoration for its own sake: a five-year goal
76
+ * should not look like a weekly one.
77
+ *
78
+ * The card is styled as interactive but is **not** operable on its own — wrap
79
+ * it in a link or button so it is reachable by keyboard, exactly as `Card`'s
80
+ * `interactive` prop documents.
81
+ *
82
+ * @remarks
83
+ * The three highest tiers carry the full prestige treatment — gradient wash,
84
+ * coloured glow shadow, corner ornament, and emblem — driven by the `ochre`,
85
+ * `sage`, and `sienna` ramps in `@manakind/manuia-tokens`.
86
+ *
87
+ * Those ramp values are interim: generated in OKLCH rather than taken from
88
+ * designed colours, so the shapes are right and the exact hues are pending a
89
+ * design pass. See issue #34.
90
+ */
91
+ export declare function GoalCard({ title, description, type, status, statusIcon, categories, maxVisibleCategories, milestones, targetDate, typeIcon, milestoneIcon, emblemIcon, titleAs, className, }: GoalCardProps): import("react/jsx-runtime").JSX.Element;
92
+ //# sourceMappingURL=goal-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal-card.d.ts","sourceRoot":"","sources":["../../src/goal-card/goal-card.tsx"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,UAAU,EAEhB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,iBAAiB,CAAC;AAEzB,uDAAuD;AACvD,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEhF,MAAM,MAAM,UAAU,GAAG,aAAa,GAAG,aAAa,GAAG,WAAW,CAAC;AAErE,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,IAAI,EAAE,QAAQ,CAAC;IACf,yCAAyC;IACzC,MAAM,EAAE,UAAU,CAAC;IACnB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,uCAAuC;IACvC,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAC5B,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,+DAA+D;IAC/D,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;IAC7B,yGAAyG;IACzG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,mEAAmE;IACnE,aAAa,CAAC,EAAE,UAAU,CAAC;IAC3B;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC7B,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA2BD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,WAAW,EACX,IAAI,EACJ,MAAM,EACN,UAAU,EACV,UAAe,EACf,oBAAwB,EACxB,UAAU,EACV,UAAU,EACV,QAAQ,EACR,aAAa,EACb,UAAU,EACV,OAAc,EACd,SAAS,GACV,EAAE,aAAa,2CA8Gf"}
@@ -0,0 +1,66 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Badge, Card, CardContent, CardHeader, CardTitle, cx, Icon, Progress, } from '@manakind/ui-core';
3
+ import { GoalCategories } from '../goal-categories';
4
+ import './goal-card.css';
5
+ const STATUS_VARIANT = {
6
+ 'Not Started': 'muted',
7
+ 'In Progress': 'info',
8
+ Completed: 'success',
9
+ };
10
+ /**
11
+ * Emblem glyph size per tier, mirroring the product (20 / 16 / 14). The ring
12
+ * around it is sized in CSS from the tier tokens; this is the icon inside it.
13
+ */
14
+ const TIER_EMBLEM_ICON_SIZE = {
15
+ '5 Year': 'lg',
16
+ '1 Year': 'md',
17
+ Quarterly: 'sm',
18
+ };
19
+ /** Maps a timeframe to its CSS tier modifier. */
20
+ const TIER_CLASS = {
21
+ '5 Year': 'legendary',
22
+ '1 Year': 'epic',
23
+ Quarterly: 'rare',
24
+ Monthly: 'common',
25
+ Weekly: 'plain',
26
+ };
27
+ /**
28
+ * A Manuia goal, rendered as a card.
29
+ *
30
+ * Composes `ui-core`'s `Card`, `Badge`, and `Progress` with Manuia's own
31
+ * concepts — timeframes, categories, milestones — which is exactly why it
32
+ * lives in the product package rather than in `ui-core`.
33
+ *
34
+ * Longer horizons are given more visual weight ("prestige tiers"). That is a
35
+ * deliberate product signal, not decoration for its own sake: a five-year goal
36
+ * should not look like a weekly one.
37
+ *
38
+ * The card is styled as interactive but is **not** operable on its own — wrap
39
+ * it in a link or button so it is reachable by keyboard, exactly as `Card`'s
40
+ * `interactive` prop documents.
41
+ *
42
+ * @remarks
43
+ * The three highest tiers carry the full prestige treatment — gradient wash,
44
+ * coloured glow shadow, corner ornament, and emblem — driven by the `ochre`,
45
+ * `sage`, and `sienna` ramps in `@manakind/manuia-tokens`.
46
+ *
47
+ * Those ramp values are interim: generated in OKLCH rather than taken from
48
+ * designed colours, so the shapes are right and the exact hues are pending a
49
+ * design pass. See issue #34.
50
+ */
51
+ export function GoalCard({ title, description, type, status, statusIcon, categories = [], maxVisibleCategories = 3, milestones, targetDate, typeIcon, milestoneIcon, emblemIcon, titleAs = 'h3', className, }) {
52
+ const completed = milestones?.filter((m) => m.completed).length ?? 0;
53
+ const total = milestones?.length ?? 0;
54
+ /*
55
+ * Three decorative, inert spans are always in the tree, and CSS decides per
56
+ * tier whether they show: the ornament frame and the four corner marks
57
+ * (brackets on 5 Year, dots on 1 Year), and the hairline closing the header
58
+ * band, which is hidden below the top two tiers.
59
+ *
60
+ * Rendered unconditionally rather than branched on `type` so the tier
61
+ * treatment stays entirely in `goal-card.css` — one place to read what a
62
+ * tier looks like, and no second definition here to drift from it.
63
+ */
64
+ return (_jsxs(Card, { interactive: true, className: cx('mui-goal-card', `mui-goal-card--${TIER_CLASS[type]}`, className), children: [_jsx("span", { className: "mui-goal-card__ornament", "aria-hidden": "true" }), _jsxs("span", { className: "mui-goal-card__corners", "aria-hidden": "true", children: [_jsx("span", {}), _jsx("span", {}), _jsx("span", {}), _jsx("span", {})] }), _jsxs(CardHeader, { className: "mui-goal-card__header", children: [_jsxs("div", { className: "mui-goal-card__meta", children: [_jsxs("span", { className: "mui-goal-card__meta-start", children: [emblemIcon && (_jsx("span", { className: "mui-goal-card__emblem", "aria-hidden": "true", children: _jsx(Icon, { source: emblemIcon, size: TIER_EMBLEM_ICON_SIZE[type] ?? 'md', decorative: true }) })), _jsxs("span", { className: "mui-goal-card__type", children: [typeIcon && _jsx(Icon, { source: typeIcon, size: "sm", decorative: true }), type] })] }), _jsx(Badge, { variant: STATUS_VARIANT[status], appearance: "plain", icon: statusIcon, "aria-label": status, children: status })] }), _jsx(GoalCategories, { className: "mui-goal-card__categories", categories: categories, maxVisible: maxVisibleCategories }), _jsx(CardTitle, { as: titleAs, className: "mui-goal-card__title", children: title }), _jsx("span", { className: "mui-goal-card__divider", "aria-hidden": "true" })] }), _jsxs(CardContent, { className: "mui-goal-card__content", children: [_jsx("p", { className: "mui-goal-card__description", children: description || 'No description provided.' }), total > 0 && (_jsxs("div", { className: "mui-goal-card__milestones", children: [_jsx(Progress, { size: "sm", value: completed, max: total, label: _jsx("span", { className: "mui-goal-card__milestones-label", children: "Milestones" }), valueText: `${completed} of ${total}` }), _jsx("ul", { className: "mui-goal-card__milestone-list", children: milestones?.map((milestone) => (_jsxs("li", { className: cx('mui-goal-card__milestone', milestone.completed && 'mui-goal-card__milestone--done'), children: [_jsx("span", { className: "mui-goal-card__milestone-marker", "aria-hidden": "true", children: milestone.completed && milestoneIcon && (_jsx(Icon, { source: milestoneIcon, size: "sm", decorative: true })) }), _jsx("span", { className: "mui-goal-card__milestone-title", children: milestone.title })] }, milestone.id))) })] })), targetDate && (_jsxs("p", { className: "mui-goal-card__target", children: [_jsx("span", { className: "mui-goal-card__target-label", children: "Target:" }), " ", targetDate] }))] })] }));
65
+ }
66
+ //# sourceMappingURL=goal-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal-card.js","sourceRoot":"","sources":["../../src/goal-card/goal-card.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,KAAK,EACL,IAAI,EACJ,WAAW,EACX,UAAU,EACV,SAAS,EACT,EAAE,EACF,IAAI,EAGJ,QAAQ,GACT,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAqB,MAAM,oBAAoB,CAAC;AACvE,OAAO,iBAAiB,CAAC;AAqEzB,MAAM,cAAc,GAAqD;IACvE,aAAa,EAAE,OAAO;IACtB,aAAa,EAAE,MAAM;IACrB,SAAS,EAAE,SAAS;CACrB,CAAC;AAEF;;;GAGG;AACH,MAAM,qBAAqB,GAAwC;IACjE,QAAQ,EAAE,IAAI;IACd,QAAQ,EAAE,IAAI;IACd,SAAS,EAAE,IAAI;CAChB,CAAC;AAEF,iDAAiD;AACjD,MAAM,UAAU,GAA6B;IAC3C,QAAQ,EAAE,WAAW;IACrB,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,MAAM;IACjB,OAAO,EAAE,QAAQ;IACjB,MAAM,EAAE,OAAO;CAChB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,QAAQ,CAAC,EACvB,KAAK,EACL,WAAW,EACX,IAAI,EACJ,MAAM,EACN,UAAU,EACV,UAAU,GAAG,EAAE,EACf,oBAAoB,GAAG,CAAC,EACxB,UAAU,EACV,UAAU,EACV,QAAQ,EACR,aAAa,EACb,UAAU,EACV,OAAO,GAAG,IAAI,EACd,SAAS,GACK;IACd,MAAM,SAAS,GAAG,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;IACrE,MAAM,KAAK,GAAG,UAAU,EAAE,MAAM,IAAI,CAAC,CAAC;IAEtC;;;;;;;;;OASG;IACH,OAAO,CACL,MAAC,IAAI,IACH,WAAW,QACX,SAAS,EAAE,EAAE,CAAC,eAAe,EAAE,kBAAkB,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,aAE/E,eAAM,SAAS,EAAC,yBAAyB,iBAAa,MAAM,GAAG,EAC/D,gBAAM,SAAS,EAAC,wBAAwB,iBAAa,MAAM,aACzD,gBAAQ,EACR,gBAAQ,EACR,gBAAQ,EACR,gBAAQ,IACH,EAEP,MAAC,UAAU,IAAC,SAAS,EAAC,uBAAuB,aAC3C,eAAK,SAAS,EAAC,qBAAqB,aAClC,gBAAM,SAAS,EAAC,2BAA2B,aACxC,UAAU,IAAI,CACb,eAAM,SAAS,EAAC,uBAAuB,iBAAa,MAAM,YACxD,KAAC,IAAI,IAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,qBAAqB,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,UAAU,SAAG,GAC7E,CACR,EACD,gBAAM,SAAS,EAAC,qBAAqB,aAClC,QAAQ,IAAI,KAAC,IAAI,IAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAC,IAAI,EAAC,UAAU,SAAG,EAC3D,IAAI,IACA,IACF,EAMP,KAAC,KAAK,IACJ,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,EAC/B,UAAU,EAAC,OAAO,EAClB,IAAI,EAAE,UAAU,gBACJ,MAAM,YAEjB,MAAM,GACD,IACJ,EAEN,KAAC,cAAc,IACb,SAAS,EAAC,2BAA2B,EACrC,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,oBAAoB,GAChC,EAEF,KAAC,SAAS,IAAC,EAAE,EAAE,OAAO,EAAE,SAAS,EAAC,sBAAsB,YACrD,KAAK,GACI,EAGZ,eAAM,SAAS,EAAC,wBAAwB,iBAAa,MAAM,GAAG,IACnD,EAEb,MAAC,WAAW,IAAC,SAAS,EAAC,wBAAwB,aAC7C,YAAG,SAAS,EAAC,4BAA4B,YAAE,WAAW,IAAI,0BAA0B,GAAK,EAExF,KAAK,GAAG,CAAC,IAAI,CACZ,eAAK,SAAS,EAAC,2BAA2B,aACxC,KAAC,QAAQ,IACP,IAAI,EAAC,IAAI,EACT,KAAK,EAAE,SAAS,EAChB,GAAG,EAAE,KAAK,EACV,KAAK,EAAE,eAAM,SAAS,EAAC,iCAAiC,2BAAkB,EAC1E,SAAS,EAAE,GAAG,SAAS,OAAO,KAAK,EAAE,GACrC,EACF,aAAI,SAAS,EAAC,+BAA+B,YAC1C,UAAU,EAAE,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAC9B,cAEE,SAAS,EAAE,EAAE,CACX,0BAA0B,EAC1B,SAAS,CAAC,SAAS,IAAI,gCAAgC,CACxD,aAED,eAAM,SAAS,EAAC,iCAAiC,iBAAa,MAAM,YACjE,SAAS,CAAC,SAAS,IAAI,aAAa,IAAI,CACvC,KAAC,IAAI,IAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAC,IAAI,EAAC,UAAU,SAAG,CACrD,GACI,EACP,eAAM,SAAS,EAAC,gCAAgC,YAAE,SAAS,CAAC,KAAK,GAAQ,KAXpE,SAAS,CAAC,EAAE,CAYd,CACN,CAAC,GACC,IACD,CACP,EAEA,UAAU,IAAI,CACb,aAAG,SAAS,EAAC,uBAAuB,aAClC,eAAM,SAAS,EAAC,6BAA6B,wBAAe,OAAE,UAAU,IACtE,CACL,IACW,IACT,CACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ export type { GoalCardProps, GoalMilestone, GoalStatus, GoalType, } from './goal-card';
2
+ export { GoalCard } from './goal-card';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/goal-card/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,aAAa,EACb,aAAa,EACb,UAAU,EACV,QAAQ,GACT,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { GoalCard } from './goal-card';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/goal-card/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,51 @@
1
+ @layer components {
2
+ .mui-goal-categories {
3
+ display: flex;
4
+ flex-wrap: wrap;
5
+ align-items: center;
6
+ gap: var(--semantic-space-gap) var(--semantic-space-gap-relaxed);
7
+ margin: 0;
8
+ padding: 0;
9
+ list-style: none;
10
+
11
+ & .mui-goal-categories__item {
12
+ display: inline-flex;
13
+ align-items: center;
14
+ gap: var(--semantic-space-gap-tight);
15
+ color: var(--semantic-color-text-muted);
16
+ font-size: var(--primitives-font-size-sm);
17
+ white-space: nowrap;
18
+ }
19
+
20
+ /*
21
+ * `--mui-goal-category` is set per item from the category's stored
22
+ * colour, falling back to the primary action colour for a category that
23
+ * has none yet.
24
+ *
25
+ * The dot is deliberately NOT load-bearing. A category colour is user
26
+ * data — any colour at all, including one that matches the card surface —
27
+ * so no contrast floor can be promised for it, and promising one would be
28
+ * a claim this component cannot keep. The name sits beside it as text on
29
+ * the card surface at that surface's own checked contrast, which is what
30
+ * actually carries the category.
31
+ *
32
+ * The ring exists so the dot does not vanish entirely against a
33
+ * near-surface colour. It is a visibility floor for a decoration, not a
34
+ * contrast guarantee.
35
+ */
36
+ & .mui-goal-categories__dot {
37
+ flex-shrink: 0;
38
+ width: var(--component-goal-categories-dot-size);
39
+ height: var(--component-goal-categories-dot-size);
40
+ border-radius: var(--semantic-radius-pill);
41
+ background-color: var(--mui-goal-category, var(--semantic-color-action-primary));
42
+ box-shadow: 0 0 0 1px var(--semantic-color-border-subtle);
43
+ }
44
+
45
+ /*
46
+ * No colour override: the overflow item is the same muted text as the
47
+ * rest, and its lack of a dot already sets it apart. It keeps a class so
48
+ * tests and products have a hook.
49
+ */
50
+ }
51
+ }
@@ -0,0 +1,55 @@
1
+ import './goal-categories.css';
2
+ export interface GoalCategory {
3
+ /** Stable identifier. */
4
+ id: string;
5
+ /** Display name. Carries the meaning — never rely on the colour alone. */
6
+ name: string;
7
+ /**
8
+ * Resolved CSS colour for this category.
9
+ *
10
+ * Category colours are **data, not design tokens** — each category row
11
+ * stores a colour the user picked, so the value arrives at runtime rather
12
+ * than from the token pipeline. It is applied through a custom property
13
+ * rather than an inline `background-color` so the CSS keeps ownership of
14
+ * how the colour is used.
15
+ *
16
+ * Validated before it reaches the style attribute — see `safeColor` and the
17
+ * comment above it. A value that is not a recognisable CSS colour is ignored.
18
+ *
19
+ * When omitted or rejected the dot falls back to the product's primary
20
+ * action colour.
21
+ */
22
+ color?: string;
23
+ }
24
+ export interface GoalCategoriesProps {
25
+ /** Categories to show. Renders nothing when empty. */
26
+ categories: GoalCategory[];
27
+ /**
28
+ * Show at most this many, then a `+N more`. Omit to show all.
29
+ *
30
+ * Normalized before use: truncated toward zero, clamped at zero, and a
31
+ * non-finite value is treated as "no limit" rather than hiding everything.
32
+ */
33
+ maxVisible?: number;
34
+ /** Extra class names. */
35
+ className?: string;
36
+ }
37
+ /**
38
+ * The categories a Manuia goal belongs to, as dotted text.
39
+ *
40
+ * A Manuia-specific composition: "a goal belongs to N categories, each with a
41
+ * user-chosen colour, collapsing after N visible" is a product concept and
42
+ * does not belong in `ui-core`.
43
+ *
44
+ * @remarks
45
+ * The name is always rendered as text on the card surface, so it inherits
46
+ * that surface's checked contrast and the grouping survives for anyone who
47
+ * cannot distinguish the colours. The dot is reinforcement, never the signal.
48
+ *
49
+ * This used to be a row of filled pills, which forced the category colour to
50
+ * be composited to 25% so text could sit on it — no fixed text colour clears
51
+ * 4.5:1 over an arbitrary user-chosen colour. Moving the colour into a dot
52
+ * removed the constraint rather than working around it.
53
+ */
54
+ export declare function GoalCategories({ categories, maxVisible, className }: GoalCategoriesProps): import("react/jsx-runtime").JSX.Element | null;
55
+ //# sourceMappingURL=goal-categories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal-categories.d.ts","sourceRoot":"","sources":["../../src/goal-categories/goal-categories.tsx"],"names":[],"mappings":"AAEA,OAAO,uBAAuB,CAAC;AA+D/B,MAAM,WAAW,YAAY;IAC3B,yBAAyB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,sDAAsD;IACtD,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,mBAAmB,kDA0CxF"}
@@ -0,0 +1,103 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cx } from '@manakind/ui-core';
3
+ import './goal-categories.css';
4
+ /*
5
+ * The colour arrives from outside the token pipeline, so this component
6
+ * validates it instead of trusting its caller.
7
+ *
8
+ * Two separate reasons, and the second is the one that bites in practice.
9
+ *
10
+ * **Injection, on the server.** React escapes HTML, not CSS. For a *custom*
11
+ * property `react-dom/server` serialises the string into the markup with only
12
+ * the five HTML entities replaced — the semicolon is not among them — so
13
+ * `red;position:fixed;inset:0` closes the declaration and the browser parses
14
+ * the tail as further rules. Enough to cover the page or hide a control.
15
+ * (React's client path goes through `style.setProperty()`, and CSSOM rejects
16
+ * a value containing `;`, so this is specifically an SSR exposure.)
17
+ *
18
+ * **Invisible dots, everywhere.** A value that is not a colour at all is the
19
+ * likelier input — a product mapping its own palette names through, say. Once
20
+ * it is *set*, the `var(--mui-goal-category, …)` fallback in the CSS no longer
21
+ * applies, and the `background-color` it feeds is invalid at computed-value
22
+ * time: the dot resolves to transparent rather than falling back. So the guard
23
+ * admits only real colour syntax; anything else is left unset, which is what
24
+ * makes the documented fallback actually happen.
25
+ *
26
+ * This outlived the pills-to-dots change. The mechanism moved — it was
27
+ * `color-mix()` going invalid, now it is `background-color` — but "a bad value
28
+ * silently paints nothing" is a property of the custom-property fallback, not
29
+ * of whatever consumed it.
30
+ */
31
+ const CSS_COLOR_FUNCTION = /^(?:rgb|hsl|hwb|lab|lch|oklab|oklch|color)a?\([^;(){}]*\)$/i;
32
+ const CSS_HEX = /^#(?:[0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;
33
+ // The CSS named colours. A bare word outside this set is rejected rather than
34
+ // passed through, because an unrecognised keyword is what produces the
35
+ // invalid-colour case above.
36
+ const CSS_NAMED_COLORS = new Set(`aliceblue antiquewhite aqua aquamarine azure beige bisque black blanchedalmond blue
37
+ blueviolet brown burlywood cadetblue chartreuse chocolate coral cornflowerblue cornsilk
38
+ crimson cyan darkblue darkcyan darkgoldenrod darkgray darkgreen darkgrey darkkhaki
39
+ darkmagenta darkolivegreen darkorange darkorchid darkred darksalmon darkseagreen
40
+ darkslateblue darkslategray darkslategrey darkturquoise darkviolet deeppink deepskyblue
41
+ dimgray dimgrey dodgerblue firebrick floralwhite forestgreen fuchsia gainsboro ghostwhite
42
+ gold goldenrod gray green greenyellow grey honeydew hotpink indianred indigo ivory khaki
43
+ lavender lavenderblush lawngreen lemonchiffon lightblue lightcoral lightcyan
44
+ lightgoldenrodyellow lightgray lightgreen lightgrey lightpink lightsalmon lightseagreen
45
+ lightskyblue lightslategray lightslategrey lightsteelblue lightyellow lime limegreen linen
46
+ magenta maroon mediumaquamarine mediumblue mediumorchid mediumpurple mediumseagreen
47
+ mediumslateblue mediumspringgreen mediumturquoise mediumvioletred midnightblue mintcream
48
+ mistyrose moccasin navajowhite navy oldlace olive olivedrab orange orangered orchid
49
+ palegoldenrod palegreen paleturquoise palevioletred papayawhip peachpuff peru pink plum
50
+ powderblue purple rebeccapurple red rosybrown royalblue saddlebrown salmon sandybrown
51
+ seagreen seashell sienna silver skyblue slateblue slategray slategrey snow springgreen
52
+ steelblue tan teal thistle tomato transparent turquoise violet wheat white whitesmoke
53
+ yellow yellowgreen`.split(/\s+/));
54
+ function safeColor(color) {
55
+ const trimmed = color?.trim();
56
+ if (!trimmed)
57
+ return undefined;
58
+ if (CSS_HEX.test(trimmed) || CSS_COLOR_FUNCTION.test(trimmed))
59
+ return trimmed;
60
+ return CSS_NAMED_COLORS.has(trimmed.toLowerCase()) ? trimmed : undefined;
61
+ }
62
+ /**
63
+ * The categories a Manuia goal belongs to, as dotted text.
64
+ *
65
+ * A Manuia-specific composition: "a goal belongs to N categories, each with a
66
+ * user-chosen colour, collapsing after N visible" is a product concept and
67
+ * does not belong in `ui-core`.
68
+ *
69
+ * @remarks
70
+ * The name is always rendered as text on the card surface, so it inherits
71
+ * that surface's checked contrast and the grouping survives for anyone who
72
+ * cannot distinguish the colours. The dot is reinforcement, never the signal.
73
+ *
74
+ * This used to be a row of filled pills, which forced the category colour to
75
+ * be composited to 25% so text could sit on it — no fixed text colour clears
76
+ * 4.5:1 over an arbitrary user-chosen colour. Moving the colour into a dot
77
+ * removed the constraint rather than working around it.
78
+ */
79
+ export function GoalCategories({ categories, maxVisible, className }) {
80
+ if (categories.length === 0)
81
+ return null;
82
+ // Normalized once, because the value feeds both an index operation and
83
+ // arithmetic and the two coerce differently: `slice` truncates a fractional
84
+ // end index while the subtraction below keeps it, so `2.5` over three
85
+ // categories would render two names and offer "+0.5 more". Negatives are
86
+ // clamped for the same reason in the other direction — `slice` reads them as
87
+ // an offset from the end, dropping a real category and overcounting the
88
+ // remainder at once. Zero stays meaningful: it collapses the set into
89
+ // "+N more". NaN is excluded rather than clamped: it survives both Math
90
+ // calls, and `slice(0, NaN)` renders nothing while `NaN > 0` suppresses the
91
+ // overflow item too — the whole list would vanish with no indicator that it
92
+ // had.
93
+ const limit = Number.isFinite(maxVisible)
94
+ ? Math.max(Math.trunc(maxVisible), 0)
95
+ : undefined;
96
+ const visible = limit === undefined ? categories : categories.slice(0, limit);
97
+ const remaining = limit === undefined ? 0 : Math.max(categories.length - limit, 0);
98
+ return (_jsxs("ul", { className: cx('mui-goal-categories', className), children: [visible.map((category) => {
99
+ const dot = safeColor(category.color);
100
+ return (_jsxs("li", { className: "mui-goal-categories__item", style: dot ? { '--mui-goal-category': dot } : undefined, children: [_jsx("span", { className: "mui-goal-categories__dot", "aria-hidden": "true" }), category.name] }, category.id));
101
+ }), remaining > 0 && (_jsxs("li", { className: "mui-goal-categories__item mui-goal-categories__item--overflow", children: ["+", remaining, " more"] }))] }));
102
+ }
103
+ //# sourceMappingURL=goal-categories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal-categories.js","sourceRoot":"","sources":["../../src/goal-categories/goal-categories.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AAEvC,OAAO,uBAAuB,CAAC;AAE/B;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,kBAAkB,GAAG,6DAA6D,CAAC;AACzF,MAAM,OAAO,GAAG,yDAAyD,CAAC;AAE1E,8EAA8E;AAC9E,uEAAuE;AACvE,6BAA6B;AAC7B,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAC9B;;;;;;;;;;;;;;;;;sBAiBoB,CAAC,KAAK,CAAC,KAAK,CAAC,CAClC,CAAC;AAEF,SAAS,SAAS,CAAC,KAAyB;IAC1C,MAAM,OAAO,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAC9E,OAAO,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3E,CAAC;AAuCD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,cAAc,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAuB;IACvF,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzC,uEAAuE;IACvE,4EAA4E;IAC5E,sEAAsE;IACtE,yEAAyE;IACzE,6EAA6E;IAC7E,wEAAwE;IACxE,sEAAsE;IACtE,wEAAwE;IACxE,4EAA4E;IAC5E,4EAA4E;IAC5E,OAAO;IACP,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;QACvC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,UAAoB,CAAC,EAAE,CAAC,CAAC;QAC/C,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,OAAO,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC9E,MAAM,SAAS,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC;IAEnF,OAAO,CACL,cAAI,SAAS,EAAE,EAAE,CAAC,qBAAqB,EAAE,SAAS,CAAC,aAChD,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;gBACxB,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACtC,OAAO,CACL,cAEE,SAAS,EAAC,2BAA2B,EACrC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAE,EAAE,qBAAqB,EAAE,GAAG,EAAoB,CAAC,CAAC,CAAC,SAAS,aAE1E,eAAM,SAAS,EAAC,0BAA0B,iBAAa,MAAM,GAAG,EAC/D,QAAQ,CAAC,IAAI,KALT,QAAQ,CAAC,EAAE,CAMb,CACN,CAAC;YACJ,CAAC,CAAC,EACD,SAAS,GAAG,CAAC,IAAI,CAChB,cAAI,SAAS,EAAC,+DAA+D,kBACzE,SAAS,aACR,CACN,IACE,CACN,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ export type { GoalCategoriesProps, GoalCategory } from './goal-categories';
2
+ export { GoalCategories } from './goal-categories';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/goal-categories/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { GoalCategories } from './goal-categories';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/goal-categories/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,10 @@
1
+ @layer components {
2
+ /*
3
+ * Set the weight through the contract variable `ui-core`'s trigger reads,
4
+ * not by out-ranking its `.ds-tabs .ds-tabs__trigger` rule: that would need
5
+ * a `ds-` class here, which only `ui-core` may use (components.md).
6
+ */
7
+ .mui-goal-tab-trigger--empty {
8
+ --ds-tabs-trigger-font-weight: var(--primitives-font-weight-regular);
9
+ }
10
+ }
@@ -0,0 +1,11 @@
1
+ import { TabsTrigger } from '@manakind/ui-core';
2
+ import type { ComponentProps } from 'react';
3
+ import './goal-tab-trigger.css';
4
+ export interface GoalTabTriggerProps extends ComponentProps<typeof TabsTrigger> {
5
+ /** Timeframe label, e.g. `Weekly`. */
6
+ label: string;
7
+ /** How many goals fall in this timeframe. */
8
+ count: number;
9
+ }
10
+ export declare function GoalTabTrigger({ label, count, className, ...props }: GoalTabTriggerProps): import("react/jsx-runtime").JSX.Element;
11
+ //# sourceMappingURL=goal-tab-trigger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal-tab-trigger.d.ts","sourceRoot":"","sources":["../../src/goal-tab-trigger/goal-tab-trigger.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAa,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,wBAAwB,CAAC;AAEhC,MAAM,WAAW,mBAAoB,SAAQ,cAAc,CAAC,OAAO,WAAW,CAAC;IAC7E,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;CACf;AA4BD,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,mBAAmB,2CAmBxF"}
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Badge, cx, TabsTrigger } from '@manakind/ui-core';
3
+ import './goal-tab-trigger.css';
4
+ /**
5
+ * A Manuia timeframe tab with its goal count.
6
+ *
7
+ * Composes `ui-core`'s `TabsTrigger` and `Badge`. The pairing is product
8
+ * specific — "a tab that carries a count of the things behind it" is a Manuia
9
+ * pattern, so it lives here rather than widening `TabsTrigger`.
10
+ *
11
+ * The count badge carries an `aria-label`, because a bare number announced
12
+ * after the label tells a screen reader user nothing. Tabs with no goals are
13
+ * rendered in a lighter weight, but they stay reachable — the count itself is
14
+ * the information.
15
+ */
16
+ /**
17
+ * Counts stop rendering their true value here and switch to `99+`.
18
+ *
19
+ * The cap bounds how wide the badge can get: without it a five-digit count
20
+ * would stretch the tab arbitrarily. At `99+` the badge widens from a circle
21
+ * into a pill, which is what every other library does with this case and
22
+ * costs nothing structurally — the height is pinned, so nothing reflows and
23
+ * the tab strip keeps its nested radii.
24
+ *
25
+ * The cap is display only. The `aria-label` always announces the real
26
+ * number, so nothing is hidden from a screen reader.
27
+ */
28
+ const MAX_DISPLAYED_COUNT = 99;
29
+ export function GoalTabTrigger({ label, count, className, ...props }) {
30
+ const hasGoals = count > 0;
31
+ const overflows = count > MAX_DISPLAYED_COUNT;
32
+ return (_jsxs(TabsTrigger, { className: cx('mui-goal-tab-trigger', !hasGoals && 'mui-goal-tab-trigger--empty', className), ...props, children: [_jsx("span", { children: label }), _jsx(Badge, { shape: "circle", variant: hasGoals ? 'success' : 'outline', "aria-label": `${count} ${count === 1 ? 'goal' : 'goals'}`, children: overflows ? `${MAX_DISPLAYED_COUNT}+` : count })] }));
33
+ }
34
+ //# sourceMappingURL=goal-tab-trigger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal-tab-trigger.js","sourceRoot":"","sources":["../../src/goal-tab-trigger/goal-tab-trigger.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,wBAAwB,CAAC;AAShC;;;;;;;;;;;GAWG;AACH;;;;;;;;;;;GAWG;AACH,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAE/B,MAAM,UAAU,cAAc,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,KAAK,EAAuB;IACvF,MAAM,QAAQ,GAAG,KAAK,GAAG,CAAC,CAAC;IAC3B,MAAM,SAAS,GAAG,KAAK,GAAG,mBAAmB,CAAC;IAE9C,OAAO,CACL,MAAC,WAAW,IACV,SAAS,EAAE,EAAE,CAAC,sBAAsB,EAAE,CAAC,QAAQ,IAAI,6BAA6B,EAAE,SAAS,CAAC,KACxF,KAAK,aAET,yBAAO,KAAK,GAAQ,EACpB,KAAC,KAAK,IACJ,KAAK,EAAC,QAAQ,EACd,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,gBAC7B,GAAG,KAAK,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,YAEvD,SAAS,CAAC,CAAC,CAAC,GAAG,mBAAmB,GAAG,CAAC,CAAC,CAAC,KAAK,GACxC,IACI,CACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ export type { GoalTabTriggerProps } from './goal-tab-trigger';
2
+ export { GoalTabTrigger } from './goal-tab-trigger';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/goal-tab-trigger/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { GoalTabTrigger } from './goal-tab-trigger';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/goal-tab-trigger/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * `@manakind/manuia-ui` is the Manuia-flavored surface of the Manakind design system.
3
+ *
4
+ * It re-exports the shared base components from `@manakind/ui-core` and adds
5
+ * the Manuia-specific compositions assembled from them.
6
+ *
7
+ * The Manuia theme is provided at runtime by importing
8
+ * `@manakind/manuia-tokens/css/theme` (and the underlying token layers) — see
9
+ * `.storybook/preview.ts` for the canonical setup.
10
+ */
11
+ export * from '@manakind/ui-core';
12
+ export * from './goal-card';
13
+ export * from './goal-categories';
14
+ export * from './goal-tab-trigger';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * `@manakind/manuia-ui` is the Manuia-flavored surface of the Manakind design system.
3
+ *
4
+ * It re-exports the shared base components from `@manakind/ui-core` and adds
5
+ * the Manuia-specific compositions assembled from them.
6
+ *
7
+ * The Manuia theme is provided at runtime by importing
8
+ * `@manakind/manuia-tokens/css/theme` (and the underlying token layers) — see
9
+ * `.storybook/preview.ts` for the canonical setup.
10
+ */
11
+ export * from '@manakind/ui-core';
12
+ export * from './goal-card';
13
+ export * from './goal-categories';
14
+ export * from './goal-tab-trigger';
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "@manakind/manuia-ui",
3
+ "version": "0.2.0",
4
+ "type": "module",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/Humanity-Plus/Manakind.git",
9
+ "directory": "packages/manuia-ui"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "sideEffects": [
18
+ "**/*.css"
19
+ ],
20
+ "main": "./dist/index.js",
21
+ "types": "./dist/index.d.ts",
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "import": "./dist/index.js"
26
+ }
27
+ },
28
+ "scripts": {
29
+ "build": "tsc -p tsconfig.build.json && bunx tsx ../ds-config/scripts/copy-assets.ts src dist .css",
30
+ "test": "vitest run --passWithNoTests",
31
+ "test:watch": "vitest",
32
+ "lint:css": "stylelint --allow-empty-input 'src/**/*.css'",
33
+ "lint": "biome lint .",
34
+ "typecheck": "tsc --noEmit",
35
+ "storybook": "storybook dev -p 6006",
36
+ "build-storybook": "storybook build",
37
+ "vr": "playwright test"
38
+ },
39
+ "dependencies": {
40
+ "@manakind/manuia-tokens": "0.2.0",
41
+ "@manakind/ui-core": "0.2.0"
42
+ },
43
+ "peerDependencies": {
44
+ "react": "^19.2.5",
45
+ "react-dom": "^19.2.5"
46
+ },
47
+ "devDependencies": {
48
+ "@manakind/ds-config": "*",
49
+ "@playwright/test": "1.63.0",
50
+ "@storybook/addon-a11y": "^10.3.6",
51
+ "@storybook/addon-docs": "^10.3.6",
52
+ "@storybook/addon-vitest": "10.3.6",
53
+ "@storybook/react-vite": "^10.3.6",
54
+ "@testing-library/jest-dom": "^6.9.1",
55
+ "@testing-library/react": "^16.3.2",
56
+ "@testing-library/user-event": "^14.6.1",
57
+ "@types/react": "^19.2.14",
58
+ "@types/react-dom": "^19.2.3",
59
+ "@vitest/browser": "4.1.11",
60
+ "@vitest/browser-playwright": "4.1.11",
61
+ "@vitest/coverage-v8": "^4.1.11",
62
+ "jest-axe": "^10.0.0",
63
+ "jsdom": "^29.1.1",
64
+ "playwright": "1.63.0",
65
+ "react": "^19.2.5",
66
+ "react-dom": "^19.2.5",
67
+ "storybook": "^10.3.6",
68
+ "storybook-addon-pseudo-states": "10.3.6",
69
+ "stylelint": "^17.9.1",
70
+ "stylelint-declaration-strict-value": "^1.11.1",
71
+ "typescript": "^6.0.3",
72
+ "vite": "^8.0.10",
73
+ "vitest": "4.1.11"
74
+ }
75
+ }