@manakind/manuia-ui 0.6.0 → 0.8.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 (43) hide show
  1. package/dist/goal-card/goal-card.css +46 -21
  2. package/dist/goal-card/goal-card.d.ts +53 -5
  3. package/dist/goal-card/goal-card.d.ts.map +1 -1
  4. package/dist/goal-card/goal-card.js +15 -17
  5. package/dist/goal-card/goal-card.js.map +1 -1
  6. package/dist/goal-card/index.d.ts +1 -1
  7. package/dist/goal-card/index.d.ts.map +1 -1
  8. package/dist/goal-card/index.js.map +1 -1
  9. package/dist/goal-list/goal-list.css +10 -0
  10. package/dist/goal-list/goal-list.css.d.ts +2 -0
  11. package/dist/goal-list/goal-list.d.ts +17 -0
  12. package/dist/goal-list/goal-list.d.ts.map +1 -0
  13. package/dist/goal-list/goal-list.js +16 -0
  14. package/dist/goal-list/goal-list.js.map +1 -0
  15. package/dist/goal-list/index.d.ts +3 -0
  16. package/dist/goal-list/index.d.ts.map +1 -0
  17. package/dist/goal-list/index.js +2 -0
  18. package/dist/goal-list/index.js.map +1 -0
  19. package/dist/goal-list-item/goal-list-item.css +112 -0
  20. package/dist/goal-list-item/goal-list-item.css.d.ts +2 -0
  21. package/dist/goal-list-item/goal-list-item.d.ts +75 -0
  22. package/dist/goal-list-item/goal-list-item.d.ts.map +1 -0
  23. package/dist/goal-list-item/goal-list-item.js +26 -0
  24. package/dist/goal-list-item/goal-list-item.js.map +1 -0
  25. package/dist/goal-list-item/index.d.ts +3 -0
  26. package/dist/goal-list-item/index.d.ts.map +1 -0
  27. package/dist/goal-list-item/index.js +2 -0
  28. package/dist/goal-list-item/index.js.map +1 -0
  29. package/dist/goal-status-menu/goal-status-menu.css +58 -0
  30. package/dist/goal-status-menu/goal-status-menu.css.d.ts +2 -0
  31. package/dist/goal-status-menu/goal-status-menu.d.ts +54 -0
  32. package/dist/goal-status-menu/goal-status-menu.d.ts.map +1 -0
  33. package/dist/goal-status-menu/goal-status-menu.js +33 -0
  34. package/dist/goal-status-menu/goal-status-menu.js.map +1 -0
  35. package/dist/goal-status-menu/index.d.ts +3 -0
  36. package/dist/goal-status-menu/index.d.ts.map +1 -0
  37. package/dist/goal-status-menu/index.js +2 -0
  38. package/dist/goal-status-menu/index.js.map +1 -0
  39. package/dist/index.d.ts +3 -0
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +3 -0
  42. package/dist/index.js.map +1 -1
  43. package/package.json +3 -3
@@ -29,10 +29,10 @@
29
29
  */
30
30
  backdrop-filter: blur(4px);
31
31
 
32
- &:hover {
33
- box-shadow: var(--mui-tier-shadow-hover, var(--semantic-elevation-raised));
34
- }
35
-
32
+ /*
33
+ * The lift is the promise of a click, so only a card with an `href` makes
34
+ * it. A static card stays put under the pointer.
35
+ */
36
36
  &[data-interactive] {
37
37
  transition:
38
38
  box-shadow 300ms cubic-bezier(0, 0, 0.2, 1),
@@ -40,6 +40,7 @@
40
40
  transform 300ms cubic-bezier(0, 0, 0.2, 1);
41
41
 
42
42
  &:hover {
43
+ box-shadow: var(--mui-tier-shadow-hover, var(--semantic-elevation-raised));
43
44
  transform: var(--mui-tier-hover-transform, none);
44
45
  }
45
46
  }
@@ -224,10 +225,11 @@
224
225
  */
225
226
  /*
226
227
  * The container query below keeps this on one line in the normal case.
227
- * `flex-wrap` stays as the fallback for the two cases it cannot cover:
228
+ * `flex-wrap` stays as the fallback for the three cases it cannot cover:
228
229
  * a card given no `statusIcon` (the badge keeps its text rather than
229
- * collapsing to a bare colour chip — see the query), and a browser
230
- * without container queries. Wrapping to a second line is a mild,
230
+ * collapsing to a bare colour chip — see the query), a `periodLabel`
231
+ * that leaves no room for the status's text (see the query), and a
232
+ * browser without container queries. Wrapping to a second line is a mild,
231
233
  * legible degradation; the card is `overflow: hidden`, so without this
232
234
  * the failure mode is a silently clipped status instead.
233
235
  */
@@ -318,20 +320,31 @@
318
320
  * Getting that backwards is what made the first attempt fire at every
319
321
  * width on the goals page.
320
322
  *
321
- * Measured across all five tiers with the label forced visible: the
322
- * widest pairing is "Quarterly" against "Not Started" at 237px, and both
323
- * `GoalType` and `GoalStatus` are closed unions, so nothing longer can
324
- * arrive. 16rem (256px) collapses before that with 19px to spare.
323
+ * Two thresholds, because the status is two different widths. Measured
324
+ * with the label forced visible, the widest pairing is "Quarterly"
325
+ * against "Not Started", and both `GoalType` and `GoalStatus` are closed
326
+ * unions, so nothing longer can arrive:
327
+ *
328
+ * - the static badge needs 237px. 16rem (256px) collapses before that
329
+ * with 19px to spare;
330
+ * - the status menu's trigger adds its chevron and padding, and needs
331
+ * 263px. 17.5rem (280px) keeps the same margin.
325
332
  *
326
- * The number has moved twice. It was 16rem against 243px until a `ui-core`
327
- * Badge change added ~12px to every status, leaving 1px of headroom — a
328
- * threshold that had silently stopped working while every check stayed
329
- * green — so it went to 17rem against 255px. The plain status badge (#177)
330
- * then dropped the chip's padding and border, bringing the row to 237px.
331
- * Re-measure this after any Badge geometry change, and keep the margin
332
- * wide enough that normal drift cannot close it.
333
+ * The badge threshold has moved twice. It was 16rem against 243px until a
334
+ * `ui-core` Badge change added ~12px to every status, leaving 1px of
335
+ * headroom — a threshold that had silently stopped working while every
336
+ * check stayed green — so it went to 17rem against 255px. The plain status
337
+ * badge (#177) then dropped the chip's padding and border, bringing the
338
+ * row to 237px. Re-measure both after any Badge or trigger geometry change,
339
+ * and keep the margin wide enough that normal drift cannot close it.
333
340
  *
334
- * The `Statuses` play function is the backstop that makes the margin
341
+ * A `periodLabel` ("Q1 2027") is left out of the measurement on purpose.
342
+ * It adds ~66px, which at the goals page's 22rem track pushes the status
343
+ * to a line of its own, and that wrap is the better outcome there: hiding
344
+ * the status's text on every quarterly card at the standard width would
345
+ * trade a readable status for a tidier row.
346
+ *
347
+ * The `Statuses` play function is the backstop that makes the margins
335
348
  * safe to reason about rather than something to over-pad: it fails if the
336
349
  * row ever overflows at a width where the label is meant to show.
337
350
  *
@@ -342,8 +355,8 @@
342
355
  * This does in CSS what Badge's `compact` prop does, because a container
343
356
  * query cannot set a prop. It hides our own `labelClassName`, never a
344
357
  * `ui-core` class. The badge is `plain`, so there is no chip to square up:
345
- * only the label goes, and its `aria-label` keeps the accessible name
346
- * identical at both widths.
358
+ * only the label goes, and its `aria-label` — and the trigger's own name —
359
+ * keep the accessible name identical at both widths.
347
360
  *
348
361
  * Badge wraps the label — and so applies this class — only when there is
349
362
  * an `icon`. A card that passed no `statusIcon` therefore keeps its text
@@ -355,6 +368,12 @@
355
368
  }
356
369
  }
357
370
 
371
+ @container mui-goal-card (max-width: 17.5rem) {
372
+ & .mui-goal-status-menu .mui-goal-card__status-label {
373
+ display: none;
374
+ }
375
+ }
376
+
358
377
  /*
359
378
  * A heading needn't differ in colour from the body; size and grouping
360
379
  * mark it. Set through the contract key `ui-core`'s title reads, so no
@@ -406,6 +425,12 @@
406
425
  color: var(--semantic-color-text-inverse);
407
426
  }
408
427
 
428
+ & .mui-goal-card__milestone-converted {
429
+ display: inline-flex;
430
+ flex-shrink: 0;
431
+ color: var(--semantic-color-text-muted);
432
+ }
433
+
409
434
  & .mui-goal-card__milestone--done {
410
435
  color: var(--semantic-color-text-muted);
411
436
  text-decoration: line-through;
@@ -1,13 +1,29 @@
1
1
  import { type IconSource } from '@manakind/ui-core';
2
+ import type { ElementType, ReactNode } from 'react';
2
3
  import { type GoalCategory } from '../goal-categories';
4
+ import { type GoalStatus } from '../goal-status-menu';
3
5
  import './goal-card.css';
4
6
  /** Manuia's goal timeframes, longest horizon first. */
5
7
  export type GoalType = '5 Year' | '1 Year' | 'Quarterly' | 'Monthly' | 'Weekly';
6
- export type GoalStatus = 'Not Started' | 'In Progress' | 'Completed';
7
8
  export interface GoalMilestone {
8
9
  id: string;
9
10
  title: string;
10
11
  completed: boolean;
12
+ /**
13
+ * The milestone has been turned into a goal of its own. Shown as a glyph
14
+ * beside the title, named "Converted to a goal" for assistive technology,
15
+ * so the glyph is never the only signal.
16
+ */
17
+ convertedToGoal?: boolean;
18
+ }
19
+ /**
20
+ * The props a `linkComponent` receives. A plain `'a'` and a router's link
21
+ * (Next's `Link`) both satisfy it.
22
+ */
23
+ export interface GoalLinkProps {
24
+ href: string;
25
+ className?: string;
26
+ children?: ReactNode;
11
27
  }
12
28
  export interface GoalCardProps {
13
29
  /** Goal title. Rendered as the card's heading. */
@@ -28,6 +44,34 @@ export interface GoalCardProps {
28
44
  * outline differs per status, not just its hue.
29
45
  */
30
46
  statusIcon?: IconSource;
47
+ /**
48
+ * Called with a newly chosen status. When set, the status badge becomes a
49
+ * button opening a menu of the three statuses (see `GoalStatusMenu`), which
50
+ * stays operable on a linked card. Without it the badge is static.
51
+ */
52
+ onStatusChange?: (status: GoalStatus) => void;
53
+ /** Chevron after the status badge when it opens a menu. See `GoalStatusMenu`'s `indicator`. */
54
+ statusMenuIndicator?: IconSource;
55
+ /** Glyph marking the current status in the status menu. See `GoalStatusMenu`'s `itemIndicator`. */
56
+ statusMenuItemIndicator?: IconSource;
57
+ /**
58
+ * Where the card leads, usually the goal's own page. The title becomes the
59
+ * link and its hit area covers the card, which then takes its interactive
60
+ * styling; the status menu stays separately operable above it.
61
+ *
62
+ * Without it the card is static: no link, no hover or focus treatment.
63
+ */
64
+ href?: string;
65
+ /**
66
+ * What renders the link: `'a'` by default, or a router's link such as
67
+ * Next's `Link`. It receives `href`, `className` and the title as children.
68
+ */
69
+ linkComponent?: ElementType<GoalLinkProps>;
70
+ /**
71
+ * The specific period, beside the timeframe: "Q3", or "Q1 2027" outside
72
+ * the current year. Formatting is the caller's job.
73
+ */
74
+ periodLabel?: string;
31
75
  /** Categories this goal belongs to. */
32
76
  categories?: GoalCategory[];
33
77
  /** How many categories to show before collapsing into `+N more`. */
@@ -45,6 +89,8 @@ export interface GoalCardProps {
45
89
  typeIcon?: IconSource;
46
90
  /** Glyph for a completed milestone. Falls back to a filled dot. */
47
91
  milestoneIcon?: IconSource;
92
+ /** Glyph marking a milestone converted into a goal. Falls back to a built-in arrow. */
93
+ milestoneConvertedIcon?: IconSource;
48
94
  /**
49
95
  * Emblem shown on the higher tiers — the product uses a crown for 5 Year,
50
96
  * a shield for 1 Year, and a compass for Quarterly.
@@ -75,9 +121,11 @@ export interface GoalCardProps {
75
121
  * deliberate product signal, not decoration for its own sake: a five-year goal
76
122
  * should not look like a weekly one.
77
123
  *
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.
124
+ * Give it an `href` and the card owns its link: the title is the link, its
125
+ * hit area stretches over the card (`ui-core`'s `CardLink`), and the status
126
+ * menu sits above it, separately operable. Don't wrap the card in a link —
127
+ * the status menu would then be a control nested inside a link, which is
128
+ * invalid and breaks keyboard and screen reader use.
81
129
  *
82
130
  * @remarks
83
131
  * The three highest tiers carry the full prestige treatment — gradient wash,
@@ -88,5 +136,5 @@ export interface GoalCardProps {
88
136
  * designed colours, so the shapes are right and the exact hues are pending a
89
137
  * design pass. See issue #34.
90
138
  */
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;
139
+ export declare function GoalCard({ title, description, type, status, statusIcon, onStatusChange, statusMenuIndicator, statusMenuItemIndicator, href, linkComponent: LinkComponent, periodLabel, categories, maxVisibleCategories, milestones, targetDate, typeIcon, milestoneIcon, milestoneConvertedIcon, emblemIcon, titleAs, className, }: GoalCardProps): import("react/jsx-runtime").JSX.Element;
92
140
  //# sourceMappingURL=goal-card.d.ts.map
@@ -1 +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,2CAkHf"}
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,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACpD,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,KAAK,UAAU,EAAkB,MAAM,qBAAqB,CAAC;AACtE,OAAO,iBAAiB,CAAC;AAEzB,uDAAuD;AACvD,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEhF,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;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;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IAC9C,+FAA+F;IAC/F,mBAAmB,CAAC,EAAE,UAAU,CAAC;IACjC,mGAAmG;IACnG,uBAAuB,CAAC,EAAE,UAAU,CAAC;IACrC;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;IAC3C;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,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,uFAAuF;IACvF,sBAAsB,CAAC,EAAE,UAAU,CAAC;IACpC;;;;;;;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;AAqBD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,WAAW,EACX,IAAI,EACJ,MAAM,EACN,UAAU,EACV,cAAc,EACd,mBAAmB,EACnB,uBAAuB,EACvB,IAAI,EACJ,aAAa,EAAE,aAAmB,EAClC,WAAW,EACX,UAAe,EACf,oBAAwB,EACxB,UAAU,EACV,UAAU,EACV,QAAQ,EACR,aAAa,EACb,sBAAuC,EACvC,UAAU,EACV,OAAc,EACd,SAAS,GACV,EAAE,aAAa,2CAyHf"}
@@ -1,12 +1,8 @@
1
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';
2
+ import { Card, CardContent, CardHeader, CardLink, CardTitle, cx, Icon, Progress, } from '@manakind/ui-core';
3
3
  import { GoalCategories } from '../goal-categories';
4
+ import { GoalStatusMenu } from '../goal-status-menu';
4
5
  import './goal-card.css';
5
- const STATUS_VARIANT = {
6
- 'Not Started': 'muted',
7
- 'In Progress': 'info',
8
- Completed: 'success',
9
- };
10
6
  /**
11
7
  * Emblem glyph size per tier, mirroring the product (20 / 16 / 14). The ring
12
8
  * around it is sized in CSS from the tier tokens; this is the icon inside it.
@@ -35,9 +31,11 @@ const TIER_CLASS = {
35
31
  * deliberate product signal, not decoration for its own sake: a five-year goal
36
32
  * should not look like a weekly one.
37
33
  *
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.
34
+ * Give it an `href` and the card owns its link: the title is the link, its
35
+ * hit area stretches over the card (`ui-core`'s `CardLink`), and the status
36
+ * menu sits above it, separately operable. Don't wrap the card in a link —
37
+ * the status menu would then be a control nested inside a link, which is
38
+ * invalid and breaks keyboard and screen reader use.
41
39
  *
42
40
  * @remarks
43
41
  * The three highest tiers carry the full prestige treatment — gradient wash,
@@ -48,15 +46,9 @@ const TIER_CLASS = {
48
46
  * designed colours, so the shapes are right and the exact hues are pending a
49
47
  * design pass. See issue #34.
50
48
  */
51
- export function GoalCard({ title, description, type, status, statusIcon, categories = [], maxVisibleCategories = 3, milestones, targetDate, typeIcon, milestoneIcon, emblemIcon, titleAs = 'h3', className, }) {
49
+ export function GoalCard({ title, description, type, status, statusIcon, onStatusChange, statusMenuIndicator, statusMenuItemIndicator, href, linkComponent: LinkComponent = 'a', periodLabel, categories = [], maxVisibleCategories = 3, milestones, targetDate, typeIcon, milestoneIcon, milestoneConvertedIcon = ConvertedArrow, emblemIcon, titleAs = 'h3', className, }) {
52
50
  const completed = milestones?.filter((m) => m.completed).length ?? 0;
53
51
  const total = milestones?.length ?? 0;
54
- /*
55
- * Labelled even though the text is visible on a wide card: the label is what
56
- * survives when the container query hides `mui-goal-card__status-label`, and
57
- * a badge cannot know which side of that query it is on.
58
- */
59
- const statusBadge = (_jsx(Badge, { variant: STATUS_VARIANT[status], appearance: "plain", icon: statusIcon, labelClassName: "mui-goal-card__status-label", "aria-label": status, children: status }));
60
52
  /*
61
53
  * Three decorative, inert spans are always in the tree, and CSS decides per
62
54
  * tier whether they show: the ornament frame and the four corner marks
@@ -67,6 +59,12 @@ export function GoalCard({ title, description, type, status, statusIcon, categor
67
59
  * treatment stays entirely in `goal-card.css` — one place to read what a
68
60
  * tier looks like, and no second definition here to drift from it.
69
61
  */
70
- 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] })] }), statusBadge] }), _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] }))] })] }));
62
+ return (_jsxs(Card, { interactive: Boolean(href), 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, periodLabel && (_jsxs("span", { className: "mui-goal-card__period", children: [' ', _jsx("span", { "aria-hidden": "true", children: "\u00B7" }), " ", periodLabel] }))] })] }), _jsx(GoalStatusMenu, { labelClassName: "mui-goal-card__status-label", status: status, statusIcon: statusIcon, onStatusChange: onStatusChange, indicator: statusMenuIndicator, itemIndicator: statusMenuItemIndicator })] }), _jsx(GoalCategories, { className: "mui-goal-card__categories", categories: categories, maxVisible: maxVisibleCategories }), _jsx(CardTitle, { as: titleAs, className: "mui-goal-card__title", children: href ? (_jsx(CardLink, { asChild: true, children: _jsx(LinkComponent, { href: href, children: title }) })) : (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.convertedToGoal && (_jsx("span", { className: "mui-goal-card__milestone-converted", children: _jsx(Icon, { source: milestoneConvertedIcon, size: "sm", label: "Converted to a goal" }) }))] }, milestone.id))) })] })), targetDate && (_jsxs("p", { className: "mui-goal-card__target", children: [_jsx("span", { className: "mui-goal-card__target-label", children: "Target:" }), " ", targetDate] }))] })] }));
71
63
  }
64
+ /*
65
+ * Fallback glyph, inlined because this package is public and may not
66
+ * reference the private icon package. Products pass their own.
67
+ */
68
+ const ConvertedArrow = (props) => (_jsx("svg", { "aria-hidden": "true", viewBox: "0 0 16 16", fill: "none", ...props, children: _jsx("path", { d: "M5 11 11 5M6 5h5v5", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }));
69
+ ConvertedArrow.displayName = 'GoalCardConvertedArrow';
72
70
  //# sourceMappingURL=goal-card.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"goal-card.js","sourceRoot":"","sources":["../../src/goal-card/goal-card.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"goal-card.js","sourceRoot":"","sources":["../../src/goal-card/goal-card.tsx"],"names":[],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- export type { GoalCardProps, GoalMilestone, GoalStatus, GoalType, } from './goal-card';
1
+ export type { GoalCardProps, GoalLinkProps, GoalMilestone, GoalType } from './goal-card';
2
2
  export { GoalCard } from './goal-card';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/goal-card/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACzF,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/goal-card/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/goal-card/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,10 @@
1
+ @layer components {
2
+ .mui-goal-list {
3
+ display: flex;
4
+ flex-direction: column;
5
+ gap: var(--semantic-space-gap);
6
+ margin: 0;
7
+ padding: 0;
8
+ list-style: none;
9
+ }
10
+ }
@@ -0,0 +1,2 @@
1
+ /* AUTOGENERATED: types for the stylesheet beside it. */
2
+ export {};
@@ -0,0 +1,17 @@
1
+ import type { ComponentProps } from 'react';
2
+ import './goal-list.css';
3
+ export interface GoalListProps extends ComponentProps<'ul'> {
4
+ /** `GoalListItem`s. Each renders its own `<li>`. */
5
+ children?: ComponentProps<'ul'>['children'];
6
+ }
7
+ /**
8
+ * The list view of Manuia's goals: a `<ul>` of `GoalListItem` rows, the
9
+ * compact counterpart to a grid of `GoalCard`s.
10
+ *
11
+ * A real list, so a screen reader announces how many goals there are and
12
+ * where in them the reader is. Name it with `aria-label` or
13
+ * `aria-labelledby` when the heading above it doesn't already say what it
14
+ * lists.
15
+ */
16
+ export declare function GoalList({ className, children, ...props }: GoalListProps): import("react/jsx-runtime").JSX.Element;
17
+ //# sourceMappingURL=goal-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal-list.d.ts","sourceRoot":"","sources":["../../src/goal-list/goal-list.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,iBAAiB,CAAC;AAEzB,MAAM,WAAW,aAAc,SAAQ,cAAc,CAAC,IAAI,CAAC;IACzD,oDAAoD;IACpD,QAAQ,CAAC,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC;CAC7C;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,aAAa,2CAMxE"}
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cx } from '@manakind/ui-core';
3
+ import './goal-list.css';
4
+ /**
5
+ * The list view of Manuia's goals: a `<ul>` of `GoalListItem` rows, the
6
+ * compact counterpart to a grid of `GoalCard`s.
7
+ *
8
+ * A real list, so a screen reader announces how many goals there are and
9
+ * where in them the reader is. Name it with `aria-label` or
10
+ * `aria-labelledby` when the heading above it doesn't already say what it
11
+ * lists.
12
+ */
13
+ export function GoalList({ className, children, ...props }) {
14
+ return (_jsx("ul", { className: cx('mui-goal-list', className), ...props, children: children }));
15
+ }
16
+ //# sourceMappingURL=goal-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal-list.js","sourceRoot":"","sources":["../../src/goal-list/goal-list.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AAEvC,OAAO,iBAAiB,CAAC;AAOzB;;;;;;;;GAQG;AACH,MAAM,UAAU,QAAQ,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAiB;IACvE,OAAO,CACL,aAAI,SAAS,EAAE,EAAE,CAAC,eAAe,EAAE,SAAS,CAAC,KAAM,KAAK,YACrD,QAAQ,GACN,CACN,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ export type { GoalListProps } from './goal-list';
2
+ export { GoalList } from './goal-list';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/goal-list/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { GoalList } from './goal-list';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/goal-list/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,112 @@
1
+ @layer components {
2
+ .mui-goal-list-item {
3
+ /*
4
+ * The row lays out by its own width, not the viewport's, so a list in a
5
+ * narrow column collapses the same way a list on a phone does. The `<li>`
6
+ * is sized by the list, never by its content, so containment is safe.
7
+ */
8
+ container: mui-goal-list-item / inline-size;
9
+
10
+ /*
11
+ * A message passed as children sits under the row, inside the same item.
12
+ * The track is pinned to the item's width: left `auto`, a word too long
13
+ * to break in the message would widen the whole row past the list.
14
+ */
15
+ display: grid;
16
+ grid-template-columns: minmax(0, 1fr);
17
+ gap: var(--semantic-space-gap-tight);
18
+
19
+ /* Through the contract keys ui-core reads, so no specificity contest with `.ds-card`. */
20
+ & .mui-goal-list-item__card {
21
+ --ds-card-padding: var(--semantic-space-padding);
22
+ --ds-card-title-font-size: var(--primitives-font-size-md);
23
+ --ds-card-title-font-weight: var(--primitives-font-weight-regular);
24
+ }
25
+
26
+ /*
27
+ * The categories' track is capped: left at `auto` it grows to their
28
+ * one-line width, and a goal with three long categories squeezed its own
29
+ * title into a sliver that the details then painted over. Capped, they
30
+ * wrap inside their share and the title keeps the rest.
31
+ */
32
+ & .mui-goal-list-item__row {
33
+ display: grid;
34
+ grid-template-columns: minmax(0, 1fr) fit-content(40%) auto;
35
+ grid-template-areas: "main categories status";
36
+ align-items: center;
37
+ gap: var(--semantic-space-gap) var(--semantic-space-gap-relaxed);
38
+ }
39
+
40
+ & .mui-goal-list-item__main {
41
+ grid-area: main;
42
+ display: flex;
43
+ flex-direction: column;
44
+ gap: var(--semantic-space-gap-tight);
45
+ min-width: 0;
46
+ }
47
+
48
+ /* As on GoalCard: size and grouping mark the heading, not colour. */
49
+ & .mui-goal-list-item__title {
50
+ --ds-card-text: var(--ds-card-text-muted);
51
+
52
+ overflow-wrap: anywhere;
53
+ }
54
+
55
+ & .mui-goal-list-item__details {
56
+ display: flex;
57
+ flex-wrap: wrap;
58
+ align-items: center;
59
+ gap: var(--semantic-space-gap-tight) var(--semantic-space-gap-relaxed);
60
+ margin: 0;
61
+ color: var(--semantic-color-text-muted);
62
+ font-size: var(--primitives-font-size-xs);
63
+ }
64
+
65
+ & .mui-goal-list-item__type {
66
+ display: inline-flex;
67
+ align-items: center;
68
+ gap: var(--semantic-space-gap-tight);
69
+ font-weight: var(--primitives-font-weight-semibold);
70
+ white-space: nowrap;
71
+ }
72
+
73
+ & .mui-goal-list-item__detail {
74
+ white-space: nowrap;
75
+ }
76
+
77
+ /* GoalCard's small-caps label, so the two views name their details alike. */
78
+ & .mui-goal-list-item__detail-label {
79
+ font-weight: var(--primitives-font-weight-semibold);
80
+ letter-spacing: 0.15em;
81
+ text-transform: uppercase;
82
+ }
83
+
84
+ & .mui-goal-list-item__categories {
85
+ grid-area: categories;
86
+ justify-content: flex-end;
87
+ }
88
+
89
+ & .mui-goal-list-item__status {
90
+ grid-area: status;
91
+ justify-self: end;
92
+ }
93
+
94
+ /*
95
+ * Narrow: the categories move to a line of their own and the status stays
96
+ * beside the title, where a reader scanning the list looks for it.
97
+ */
98
+ @container mui-goal-list-item (max-width: 36rem) {
99
+ & .mui-goal-list-item__row {
100
+ grid-template-columns: minmax(0, 1fr) auto;
101
+ grid-template-areas:
102
+ "main status"
103
+ "categories categories";
104
+ align-items: start;
105
+ }
106
+
107
+ & .mui-goal-list-item__categories {
108
+ justify-content: flex-start;
109
+ }
110
+ }
111
+ }
112
+ }
@@ -0,0 +1,2 @@
1
+ /* AUTOGENERATED: types for the stylesheet beside it. */
2
+ export {};
@@ -0,0 +1,75 @@
1
+ import { type IconSource } from '@manakind/ui-core';
2
+ import type { ElementType, ReactNode } from 'react';
3
+ import type { GoalLinkProps, GoalMilestone, GoalType } from '../goal-card';
4
+ import { type GoalCategory } from '../goal-categories';
5
+ import { type GoalStatus } from '../goal-status-menu';
6
+ import './goal-list-item.css';
7
+ export interface GoalListItemProps {
8
+ /** Goal title. Rendered as the row's heading, and as its link when there is an `href`. */
9
+ title: string;
10
+ /** Timeframe, shown as text beside its icon. */
11
+ type: GoalType;
12
+ /** Progress status, shown as a badge. */
13
+ status: GoalStatus;
14
+ /**
15
+ * Glyph for the status, supplied by the product. Strongly recommended, for
16
+ * `GoalCard`'s reason: a glyph whose outline differs per status keeps the
17
+ * status readable without its colour.
18
+ */
19
+ statusIcon?: IconSource;
20
+ /**
21
+ * Called with a newly chosen status. When set, the status badge opens a
22
+ * menu of the three statuses, separately operable from the row's link.
23
+ */
24
+ onStatusChange?: (status: GoalStatus) => void;
25
+ /** Chevron after the status badge when it opens a menu. See `GoalStatusMenu`'s `indicator`. */
26
+ statusMenuIndicator?: IconSource;
27
+ /** Glyph marking the current status in the status menu. See `GoalStatusMenu`'s `itemIndicator`. */
28
+ statusMenuItemIndicator?: IconSource;
29
+ /** The specific period beside the timeframe, such as "Q3" or "Q1 2027". Formatted by the caller. */
30
+ periodLabel?: string;
31
+ /** Categories this goal belongs to. */
32
+ categories?: GoalCategory[];
33
+ /** How many categories to show before collapsing into `+N more`. Defaults to 2, a row being narrower than a card. */
34
+ maxVisibleCategories?: number;
35
+ /** Milestones, summarised as "Milestones 2 of 3". */
36
+ milestones?: GoalMilestone[];
37
+ /** Pre-formatted target date. */
38
+ targetDate?: string;
39
+ /** Icon beside the timeframe, supplied by the product. */
40
+ typeIcon?: IconSource;
41
+ /**
42
+ * Where the row leads. The title becomes the link and its hit area covers
43
+ * the row; without it the row is static.
44
+ */
45
+ href?: string;
46
+ /** What renders the link: `'a'` by default, or a router's link such as Next's `Link`. */
47
+ linkComponent?: ElementType<GoalLinkProps>;
48
+ /** Heading level for the title. Defaults to `h3`; match the surrounding outline. */
49
+ titleAs?: 'h2' | 'h3' | 'h4';
50
+ /** Extra class names on the `<li>`. */
51
+ className?: string;
52
+ /**
53
+ * A message about this goal, shown under the row inside the same `<li>`:
54
+ * an `Alert` after a failed status change, say. Kept in the item so the
55
+ * list's item count stays the number of goals.
56
+ */
57
+ children?: ReactNode;
58
+ }
59
+ /**
60
+ * One Manuia goal as a compact row, for the list view. Render it inside a
61
+ * `GoalList`: it is the `<li>`.
62
+ *
63
+ * Carries what `GoalCard` does where a row has room for it — title,
64
+ * timeframe and period, categories, a milestone count, target date and the
65
+ * status — and leaves out the description, the milestone checklist and the
66
+ * prestige-tier decoration. Behaves like the card: with an `href` the title is
67
+ * the link and its hit area stretches over the row, and the status menu sits
68
+ * above it, separately operable.
69
+ *
70
+ * Wide, the row reads left to right: title over its details, then categories,
71
+ * then status. Narrow, the categories drop below and the status stays beside
72
+ * the title.
73
+ */
74
+ export declare function GoalListItem({ title, type, status, statusIcon, onStatusChange, statusMenuIndicator, statusMenuItemIndicator, periodLabel, categories, maxVisibleCategories, milestones, targetDate, typeIcon, href, linkComponent: LinkComponent, titleAs, className, children, }: GoalListItemProps): import("react/jsx-runtime").JSX.Element;
75
+ //# sourceMappingURL=goal-list-item.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal-list-item.d.ts","sourceRoot":"","sources":["../../src/goal-list-item/goal-list-item.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuC,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACzF,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,KAAK,UAAU,EAAkB,MAAM,qBAAqB,CAAC;AACtE,OAAO,sBAAsB,CAAC;AAE9B,MAAM,WAAW,iBAAiB;IAChC,0FAA0F;IAC1F,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,IAAI,EAAE,QAAQ,CAAC;IACf,yCAAyC;IACzC,MAAM,EAAE,UAAU,CAAC;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IAC9C,+FAA+F;IAC/F,mBAAmB,CAAC,EAAE,UAAU,CAAC;IACjC,mGAAmG;IACnG,uBAAuB,CAAC,EAAE,UAAU,CAAC;IACrC,oGAAoG;IACpG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uCAAuC;IACvC,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAC5B,qHAAqH;IACrH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,qDAAqD;IACrD,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;IAC7B,iCAAiC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yFAAyF;IACzF,aAAa,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;IAC3C,oFAAoF;IACpF,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC7B,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,IAAI,EACJ,MAAM,EACN,UAAU,EACV,cAAc,EACd,mBAAmB,EACnB,uBAAuB,EACvB,WAAW,EACX,UAAe,EACf,oBAAwB,EACxB,UAAU,EACV,UAAU,EACV,QAAQ,EACR,IAAI,EACJ,aAAa,EAAE,aAAmB,EAClC,OAAc,EACd,SAAS,EACT,QAAQ,GACT,EAAE,iBAAiB,2CA+DnB"}
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Card, CardLink, CardTitle, cx, Icon } from '@manakind/ui-core';
3
+ import { GoalCategories } from '../goal-categories';
4
+ import { GoalStatusMenu } from '../goal-status-menu';
5
+ import './goal-list-item.css';
6
+ /**
7
+ * One Manuia goal as a compact row, for the list view. Render it inside a
8
+ * `GoalList`: it is the `<li>`.
9
+ *
10
+ * Carries what `GoalCard` does where a row has room for it — title,
11
+ * timeframe and period, categories, a milestone count, target date and the
12
+ * status — and leaves out the description, the milestone checklist and the
13
+ * prestige-tier decoration. Behaves like the card: with an `href` the title is
14
+ * the link and its hit area stretches over the row, and the status menu sits
15
+ * above it, separately operable.
16
+ *
17
+ * Wide, the row reads left to right: title over its details, then categories,
18
+ * then status. Narrow, the categories drop below and the status stays beside
19
+ * the title.
20
+ */
21
+ export function GoalListItem({ title, type, status, statusIcon, onStatusChange, statusMenuIndicator, statusMenuItemIndicator, periodLabel, categories = [], maxVisibleCategories = 2, milestones, targetDate, typeIcon, href, linkComponent: LinkComponent = 'a', titleAs = 'h3', className, children, }) {
22
+ const completed = milestones?.filter((m) => m.completed).length ?? 0;
23
+ const total = milestones?.length ?? 0;
24
+ return (_jsxs("li", { className: cx('mui-goal-list-item', className), children: [_jsx(Card, { interactive: Boolean(href), className: "mui-goal-list-item__card", children: _jsxs("div", { className: "mui-goal-list-item__row", children: [_jsxs("div", { className: "mui-goal-list-item__main", children: [_jsx(CardTitle, { as: titleAs, className: "mui-goal-list-item__title", children: href ? (_jsx(CardLink, { asChild: true, children: _jsx(LinkComponent, { href: href, children: title }) })) : (title) }), _jsxs("p", { className: "mui-goal-list-item__details", children: [_jsxs("span", { className: "mui-goal-list-item__type", children: [typeIcon && _jsx(Icon, { source: typeIcon, size: "sm", decorative: true }), type, periodLabel && (_jsxs("span", { className: "mui-goal-list-item__period", children: [' ', _jsx("span", { "aria-hidden": "true", children: "\u00B7" }), " ", periodLabel] }))] }), total > 0 && (_jsxs("span", { className: "mui-goal-list-item__detail", children: [_jsx("span", { className: "mui-goal-list-item__detail-label", children: "Milestones" }), " ", completed, ' ', "of ", total] })), targetDate && (_jsxs("span", { className: "mui-goal-list-item__detail", children: [_jsx("span", { className: "mui-goal-list-item__detail-label", children: "Target:" }), " ", targetDate] }))] })] }), _jsx(GoalCategories, { className: "mui-goal-list-item__categories", categories: categories, maxVisible: maxVisibleCategories }), _jsx(GoalStatusMenu, { className: "mui-goal-list-item__status", status: status, statusIcon: statusIcon, onStatusChange: onStatusChange, indicator: statusMenuIndicator, itemIndicator: statusMenuItemIndicator })] }) }), children] }));
25
+ }
26
+ //# sourceMappingURL=goal-list-item.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal-list-item.js","sourceRoot":"","sources":["../../src/goal-list-item/goal-list-item.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAmB,MAAM,mBAAmB,CAAC;AAGzF,OAAO,EAAE,cAAc,EAAqB,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAmB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,sBAAsB,CAAC;AAuD9B;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,YAAY,CAAC,EAC3B,KAAK,EACL,IAAI,EACJ,MAAM,EACN,UAAU,EACV,cAAc,EACd,mBAAmB,EACnB,uBAAuB,EACvB,WAAW,EACX,UAAU,GAAG,EAAE,EACf,oBAAoB,GAAG,CAAC,EACxB,UAAU,EACV,UAAU,EACV,QAAQ,EACR,IAAI,EACJ,aAAa,EAAE,aAAa,GAAG,GAAG,EAClC,OAAO,GAAG,IAAI,EACd,SAAS,EACT,QAAQ,GACU;IAClB,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,OAAO,CACL,cAAI,SAAS,EAAE,EAAE,CAAC,oBAAoB,EAAE,SAAS,CAAC,aAChD,KAAC,IAAI,IAAC,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAC,0BAA0B,YACpE,eAAK,SAAS,EAAC,yBAAyB,aACtC,eAAK,SAAS,EAAC,0BAA0B,aACvC,KAAC,SAAS,IAAC,EAAE,EAAE,OAAO,EAAE,SAAS,EAAC,2BAA2B,YAC1D,IAAI,CAAC,CAAC,CAAC,CACN,KAAC,QAAQ,IAAC,OAAO,kBACf,KAAC,aAAa,IAAC,IAAI,EAAE,IAAI,YAAG,KAAK,GAAiB,GACzC,CACZ,CAAC,CAAC,CAAC,CACF,KAAK,CACN,GACS,EAEZ,aAAG,SAAS,EAAC,6BAA6B,aACxC,gBAAM,SAAS,EAAC,0BAA0B,aACvC,QAAQ,IAAI,KAAC,IAAI,IAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAC,IAAI,EAAC,UAAU,SAAG,EAC3D,IAAI,EACJ,WAAW,IAAI,CACd,gBAAM,SAAS,EAAC,4BAA4B,aACzC,GAAG,EACJ,8BAAkB,MAAM,uBAAS,OAAE,WAAW,IACzC,CACR,IACI,EACN,KAAK,GAAG,CAAC,IAAI,CACZ,gBAAM,SAAS,EAAC,4BAA4B,aAC1C,eAAM,SAAS,EAAC,kCAAkC,2BAAkB,OAAE,SAAS,EAAE,GAAG,SAChF,KAAK,IACJ,CACR,EACA,UAAU,IAAI,CACb,gBAAM,SAAS,EAAC,4BAA4B,aAC1C,eAAM,SAAS,EAAC,kCAAkC,wBAAe,OAAE,UAAU,IACxE,CACR,IACC,IACA,EAEN,KAAC,cAAc,IACb,SAAS,EAAC,gCAAgC,EAC1C,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,oBAAoB,GAChC,EAEF,KAAC,cAAc,IACb,SAAS,EAAC,4BAA4B,EACtC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,mBAAmB,EAC9B,aAAa,EAAE,uBAAuB,GACtC,IACE,GACD,EACN,QAAQ,IACN,CACN,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ export type { GoalListItemProps } from './goal-list-item';
2
+ export { GoalListItem } from './goal-list-item';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/goal-list-item/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { GoalListItem } from './goal-list-item';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/goal-list-item/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,58 @@
1
+ @layer components {
2
+ /*
3
+ * A bare button around the plain status badge. The badge keeps its own look;
4
+ * the button adds only what says "this opens something": the chevron, a fill
5
+ * on hover, and the focus ring.
6
+ */
7
+ /*
8
+ * The trigger raises itself above a host card's stretched link (ui-core's
9
+ * CardLink), so it keeps its own clicks wherever it sits. Only the trigger:
10
+ * the static badge stays under the link, so a click on it opens the goal
11
+ * like the rest of the card. 1 is the `raised` stacking layer
12
+ * (ds-config/scripts/stacking.ts).
13
+ */
14
+ .mui-goal-status-menu {
15
+ position: relative;
16
+ z-index: 1;
17
+ display: inline-flex;
18
+ align-items: center;
19
+ flex-shrink: 0;
20
+ gap: var(--semantic-space-gap-tight);
21
+ margin: 0;
22
+ padding: 0 var(--semantic-space-gap-tight);
23
+ border: 0;
24
+ border-radius: var(--semantic-radius-interactive);
25
+ background-color: transparent;
26
+ color: inherit;
27
+ font: inherit;
28
+ cursor: pointer;
29
+ transition: background-color 150ms cubic-bezier(0, 0, 0.2, 1);
30
+
31
+ &:hover,
32
+ &[data-state="open"] {
33
+ background-color: var(--semantic-color-surface-muted);
34
+ }
35
+
36
+ &:focus-visible {
37
+ outline: 2px solid var(--semantic-color-focus-ring);
38
+ outline-offset: 3px;
39
+ }
40
+
41
+ & .mui-goal-status-menu__indicator {
42
+ color: var(--semantic-color-text-muted);
43
+ transform: rotate(90deg);
44
+ transition: transform 150ms cubic-bezier(0, 0, 0.2, 1);
45
+ }
46
+
47
+ &[data-state="open"] .mui-goal-status-menu__indicator {
48
+ transform: rotate(-90deg);
49
+ }
50
+ }
51
+ }
52
+
53
+ @media (prefers-reduced-motion: reduce) {
54
+ .mui-goal-status-menu,
55
+ .mui-goal-status-menu .mui-goal-status-menu__indicator {
56
+ transition: none;
57
+ }
58
+ }
@@ -0,0 +1,2 @@
1
+ /* AUTOGENERATED: types for the stylesheet beside it. */
2
+ export {};
@@ -0,0 +1,54 @@
1
+ import { type IconSource } from '@manakind/ui-core';
2
+ import './goal-status-menu.css';
3
+ /** A Manuia goal's progress states, in the order a goal moves through them. */
4
+ export declare const GOAL_STATUSES: readonly ["Not Started", "In Progress", "Completed"];
5
+ export type GoalStatus = (typeof GOAL_STATUSES)[number];
6
+ export interface GoalStatusMenuProps {
7
+ /** The goal's current status, shown as a badge. */
8
+ status: GoalStatus;
9
+ /**
10
+ * Glyph for the current status, supplied by the product so this package
11
+ * never imports an icon set. Pass one whose outline differs per status:
12
+ * a host may hide the badge's text through `labelClassName`, and the
13
+ * glyph is what is left.
14
+ */
15
+ statusIcon?: IconSource;
16
+ /**
17
+ * Called with the newly chosen status. When set, the badge becomes a
18
+ * button that opens a menu of the three statuses, the current one checked.
19
+ * Choosing the current status again closes the menu without calling this.
20
+ * Without it the badge is a plain, non-interactive status.
21
+ */
22
+ onStatusChange?: (status: GoalStatus) => void;
23
+ /**
24
+ * Glyph after the badge saying it opens a menu. Must point RIGHT, as
25
+ * Select's indicator does: it is turned down while closed and up while
26
+ * open, because the product's icon set has no down or up chevron.
27
+ * Defaults to a plain built-in chevron.
28
+ */
29
+ indicator?: IconSource;
30
+ /** Glyph marking the current status in the menu. Defaults to Menu's built-in check. */
31
+ itemIndicator?: IconSource;
32
+ /**
33
+ * A class for the badge's text, so a host can hide it when space runs out
34
+ * (GoalCard does, from a container query). The badge keeps its status as
35
+ * its accessible name, and the trigger keeps its own, so nothing is lost.
36
+ */
37
+ labelClassName?: string;
38
+ /** Extra class names on the outermost element: the trigger, or the badge when static. */
39
+ className?: string;
40
+ }
41
+ /**
42
+ * A goal's status badge which, given `onStatusChange`, opens a menu to change
43
+ * the status in place.
44
+ *
45
+ * Shared by `GoalCard` and `GoalListItem`. Inside a card or row that links to
46
+ * the goal, the trigger sits above the stretched link, so it keeps its own
47
+ * clicks and its own place in the tab order. The static badge does not: a
48
+ * click on it opens the goal like the rest of the card.
49
+ *
50
+ * The trigger is named "Status: In Progress. Change status": the current
51
+ * status and what pressing it does, which also names the menu it opens.
52
+ */
53
+ export declare function GoalStatusMenu({ status, statusIcon, onStatusChange, indicator, itemIndicator, labelClassName, className, }: GoalStatusMenuProps): import("react/jsx-runtime").JSX.Element;
54
+ //# sourceMappingURL=goal-status-menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal-status-menu.d.ts","sourceRoot":"","sources":["../../src/goal-status-menu/goal-status-menu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,UAAU,EAGhB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,wBAAwB,CAAC;AAEhC,+EAA+E;AAC/E,eAAO,MAAM,aAAa,sDAAuD,CAAC;AAElF,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAaxD,MAAM,WAAW,mBAAmB;IAClC,mDAAmD;IACnD,MAAM,EAAE,UAAU,CAAC;IACnB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IAC9C;;;;;OAKG;IACH,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,uFAAuF;IACvF,aAAa,CAAC,EAAE,UAAU,CAAC;IAC3B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yFAAyF;IACzF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,UAAU,EACV,cAAc,EACd,SAAgC,EAChC,aAAa,EACb,cAAc,EACd,SAAS,GACV,EAAE,mBAAmB,2CAwCrB"}
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Badge, cx, FallbackChevronRight, Icon, Menu, } from '@manakind/ui-core';
3
+ import './goal-status-menu.css';
4
+ /** A Manuia goal's progress states, in the order a goal moves through them. */
5
+ export const GOAL_STATUSES = ['Not Started', 'In Progress', 'Completed'];
6
+ const STATUS_VARIANT = {
7
+ 'Not Started': 'muted',
8
+ 'In Progress': 'info',
9
+ Completed: 'success',
10
+ };
11
+ const STATUS_ITEMS = GOAL_STATUSES.map((status) => ({
12
+ value: status,
13
+ label: status,
14
+ }));
15
+ /**
16
+ * A goal's status badge which, given `onStatusChange`, opens a menu to change
17
+ * the status in place.
18
+ *
19
+ * Shared by `GoalCard` and `GoalListItem`. Inside a card or row that links to
20
+ * the goal, the trigger sits above the stretched link, so it keeps its own
21
+ * clicks and its own place in the tab order. The static badge does not: a
22
+ * click on it opens the goal like the rest of the card.
23
+ *
24
+ * The trigger is named "Status: In Progress. Change status": the current
25
+ * status and what pressing it does, which also names the menu it opens.
26
+ */
27
+ export function GoalStatusMenu({ status, statusIcon, onStatusChange, indicator = FallbackChevronRight, itemIndicator, labelClassName, className, }) {
28
+ const badge = (_jsx(Badge, { variant: STATUS_VARIANT[status], appearance: "plain", icon: statusIcon, labelClassName: cx('mui-goal-status-menu__label', labelClassName), "aria-label": status, className: onStatusChange ? undefined : className, children: status }));
29
+ if (!onStatusChange)
30
+ return badge;
31
+ return (_jsx(Menu, { label: "Status", items: STATUS_ITEMS, value: status, onValueChange: onStatusChange, itemIndicator: itemIndicator, trigger: _jsxs("button", { type: "button", className: cx('mui-goal-status-menu', className), "aria-label": `Status: ${status}. Change status`, children: [badge, _jsx(Icon, { source: indicator, size: "sm", decorative: true, className: "mui-goal-status-menu__indicator" })] }) }));
32
+ }
33
+ //# sourceMappingURL=goal-status-menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal-status-menu.js","sourceRoot":"","sources":["../../src/goal-status-menu/goal-status-menu.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,KAAK,EACL,EAAE,EACF,oBAAoB,EACpB,IAAI,EAEJ,IAAI,GAEL,MAAM,mBAAmB,CAAC;AAC3B,OAAO,wBAAwB,CAAC;AAEhC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,aAAa,EAAE,aAAa,EAAE,WAAW,CAAU,CAAC;AAIlF,MAAM,cAAc,GAAqD;IACvE,aAAa,EAAE,OAAO;IACtB,aAAa,EAAE,MAAM;IACrB,SAAS,EAAE,SAAS;CACrB,CAAC;AAEF,MAAM,YAAY,GAA2B,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC1E,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,MAAM;CACd,CAAC,CAAC,CAAC;AAsCJ;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAAC,EAC7B,MAAM,EACN,UAAU,EACV,cAAc,EACd,SAAS,GAAG,oBAAoB,EAChC,aAAa,EACb,cAAc,EACd,SAAS,GACW;IACpB,MAAM,KAAK,GAAG,CACZ,KAAC,KAAK,IACJ,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,EAC/B,UAAU,EAAC,OAAO,EAClB,IAAI,EAAE,UAAU,EAChB,cAAc,EAAE,EAAE,CAAC,6BAA6B,EAAE,cAAc,CAAC,gBACrD,MAAM,EAClB,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,YAEhD,MAAM,GACD,CACT,CAAC;IAEF,IAAI,CAAC,cAAc;QAAE,OAAO,KAAK,CAAC;IAElC,OAAO,CACL,KAAC,IAAI,IACH,KAAK,EAAC,QAAQ,EACd,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,cAAc,EAC7B,aAAa,EAAE,aAAa,EAC5B,OAAO,EACL,kBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,EAAE,CAAC,sBAAsB,EAAE,SAAS,CAAC,gBACpC,WAAW,MAAM,iBAAiB,aAE7C,KAAK,EACN,KAAC,IAAI,IACH,MAAM,EAAE,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,UAAU,QACV,SAAS,EAAC,iCAAiC,GAC3C,IACK,GAEX,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ export type { GoalStatus, GoalStatusMenuProps } from './goal-status-menu';
2
+ export { GoalStatusMenu } from './goal-status-menu';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/goal-status-menu/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { GoalStatusMenu } from './goal-status-menu';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/goal-status-menu/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -12,5 +12,8 @@ export * from '@manakind/ui-core';
12
12
  export * from './category-card';
13
13
  export * from './goal-card';
14
14
  export * from './goal-categories';
15
+ export * from './goal-list';
16
+ export * from './goal-list-item';
17
+ export * from './goal-status-menu';
15
18
  export * from './goal-tab-trigger';
16
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -12,5 +12,8 @@ export * from '@manakind/ui-core';
12
12
  export * from './category-card';
13
13
  export * from './goal-card';
14
14
  export * from './goal-categories';
15
+ export * from './goal-list';
16
+ export * from './goal-list-item';
17
+ export * from './goal-status-menu';
15
18
  export * from './goal-tab-trigger';
16
19
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@manakind/manuia-ui",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -37,8 +37,8 @@
37
37
  "vr": "playwright test"
38
38
  },
39
39
  "dependencies": {
40
- "@manakind/manuia-tokens": "0.6.0",
41
- "@manakind/ui-core": "0.6.0"
40
+ "@manakind/manuia-tokens": "0.7.0",
41
+ "@manakind/ui-core": "0.7.1"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "react": "^19.0.0",