@manakind/manuia-ui 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/goal-card/goal-card.css +46 -21
- package/dist/goal-card/goal-card.d.ts +53 -5
- package/dist/goal-card/goal-card.d.ts.map +1 -1
- package/dist/goal-card/goal-card.js +15 -17
- package/dist/goal-card/goal-card.js.map +1 -1
- package/dist/goal-card/index.d.ts +1 -1
- package/dist/goal-card/index.d.ts.map +1 -1
- package/dist/goal-card/index.js.map +1 -1
- package/dist/goal-list/goal-list.css +10 -0
- package/dist/goal-list/goal-list.css.d.ts +2 -0
- package/dist/goal-list/goal-list.d.ts +17 -0
- package/dist/goal-list/goal-list.d.ts.map +1 -0
- package/dist/goal-list/goal-list.js +16 -0
- package/dist/goal-list/goal-list.js.map +1 -0
- package/dist/goal-list/index.d.ts +3 -0
- package/dist/goal-list/index.d.ts.map +1 -0
- package/dist/goal-list/index.js +2 -0
- package/dist/goal-list/index.js.map +1 -0
- package/dist/goal-list-item/goal-list-item.css +103 -0
- package/dist/goal-list-item/goal-list-item.css.d.ts +2 -0
- package/dist/goal-list-item/goal-list-item.d.ts +69 -0
- package/dist/goal-list-item/goal-list-item.d.ts.map +1 -0
- package/dist/goal-list-item/goal-list-item.js +26 -0
- package/dist/goal-list-item/goal-list-item.js.map +1 -0
- package/dist/goal-list-item/index.d.ts +3 -0
- package/dist/goal-list-item/index.d.ts.map +1 -0
- package/dist/goal-list-item/index.js +2 -0
- package/dist/goal-list-item/index.js.map +1 -0
- package/dist/goal-status-menu/goal-status-menu.css +58 -0
- package/dist/goal-status-menu/goal-status-menu.css.d.ts +2 -0
- package/dist/goal-status-menu/goal-status-menu.d.ts +54 -0
- package/dist/goal-status-menu/goal-status-menu.d.ts.map +1 -0
- package/dist/goal-status-menu/goal-status-menu.js +33 -0
- package/dist/goal-status-menu/goal-status-menu.js.map +1 -0
- package/dist/goal-status-menu/index.d.ts +3 -0
- package/dist/goal-status-menu/index.d.ts.map +1 -0
- package/dist/goal-status-menu/index.js +2 -0
- package/dist/goal-status-menu/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
*/
|
|
30
30
|
backdrop-filter: blur(4px);
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
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
|
|
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),
|
|
230
|
-
*
|
|
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
|
-
*
|
|
322
|
-
* widest pairing is "Quarterly"
|
|
323
|
-
* `GoalType` and `GoalStatus` are closed
|
|
324
|
-
*
|
|
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
|
|
327
|
-
* Badge change added ~12px to every status, leaving 1px of
|
|
328
|
-
* threshold that had silently stopped working while every
|
|
329
|
-
* green — so it went to 17rem against 255px. The plain status
|
|
330
|
-
* then dropped the chip's padding and border, bringing the
|
|
331
|
-
* Re-measure
|
|
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
|
-
*
|
|
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`
|
|
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
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
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,
|
|
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 {
|
|
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
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
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:
|
|
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":";AAAA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"goal-card.js","sourceRoot":"","sources":["../../src/goal-card/goal-card.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/goal-card/index.ts"],"names":[],"mappings":"AAAA,YAAY,
|
|
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":"
|
|
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,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 @@
|
|
|
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 @@
|
|
|
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,103 @@
|
|
|
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
|
+
/* Through the contract keys ui-core reads, so no specificity contest with `.ds-card`. */
|
|
11
|
+
& .mui-goal-list-item__card {
|
|
12
|
+
--ds-card-padding: var(--semantic-space-padding);
|
|
13
|
+
--ds-card-title-font-size: var(--primitives-font-size-md);
|
|
14
|
+
--ds-card-title-font-weight: var(--primitives-font-weight-regular);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/*
|
|
18
|
+
* The categories' track is capped: left at `auto` it grows to their
|
|
19
|
+
* one-line width, and a goal with three long categories squeezed its own
|
|
20
|
+
* title into a sliver that the details then painted over. Capped, they
|
|
21
|
+
* wrap inside their share and the title keeps the rest.
|
|
22
|
+
*/
|
|
23
|
+
& .mui-goal-list-item__row {
|
|
24
|
+
display: grid;
|
|
25
|
+
grid-template-columns: minmax(0, 1fr) fit-content(40%) auto;
|
|
26
|
+
grid-template-areas: "main categories status";
|
|
27
|
+
align-items: center;
|
|
28
|
+
gap: var(--semantic-space-gap) var(--semantic-space-gap-relaxed);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
& .mui-goal-list-item__main {
|
|
32
|
+
grid-area: main;
|
|
33
|
+
display: flex;
|
|
34
|
+
flex-direction: column;
|
|
35
|
+
gap: var(--semantic-space-gap-tight);
|
|
36
|
+
min-width: 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* As on GoalCard: size and grouping mark the heading, not colour. */
|
|
40
|
+
& .mui-goal-list-item__title {
|
|
41
|
+
--ds-card-text: var(--ds-card-text-muted);
|
|
42
|
+
|
|
43
|
+
overflow-wrap: anywhere;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
& .mui-goal-list-item__details {
|
|
47
|
+
display: flex;
|
|
48
|
+
flex-wrap: wrap;
|
|
49
|
+
align-items: center;
|
|
50
|
+
gap: var(--semantic-space-gap-tight) var(--semantic-space-gap-relaxed);
|
|
51
|
+
margin: 0;
|
|
52
|
+
color: var(--semantic-color-text-muted);
|
|
53
|
+
font-size: var(--primitives-font-size-xs);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
& .mui-goal-list-item__type {
|
|
57
|
+
display: inline-flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
gap: var(--semantic-space-gap-tight);
|
|
60
|
+
font-weight: var(--primitives-font-weight-semibold);
|
|
61
|
+
white-space: nowrap;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
& .mui-goal-list-item__detail {
|
|
65
|
+
white-space: nowrap;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* GoalCard's small-caps label, so the two views name their details alike. */
|
|
69
|
+
& .mui-goal-list-item__detail-label {
|
|
70
|
+
font-weight: var(--primitives-font-weight-semibold);
|
|
71
|
+
letter-spacing: 0.15em;
|
|
72
|
+
text-transform: uppercase;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
& .mui-goal-list-item__categories {
|
|
76
|
+
grid-area: categories;
|
|
77
|
+
justify-content: flex-end;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
& .mui-goal-list-item__status {
|
|
81
|
+
grid-area: status;
|
|
82
|
+
justify-self: end;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/*
|
|
86
|
+
* Narrow: the categories move to a line of their own and the status stays
|
|
87
|
+
* beside the title, where a reader scanning the list looks for it.
|
|
88
|
+
*/
|
|
89
|
+
@container mui-goal-list-item (max-width: 36rem) {
|
|
90
|
+
& .mui-goal-list-item__row {
|
|
91
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
92
|
+
grid-template-areas:
|
|
93
|
+
"main status"
|
|
94
|
+
"categories categories";
|
|
95
|
+
align-items: start;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
& .mui-goal-list-item__categories {
|
|
99
|
+
justify-content: flex-start;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { type IconSource } from '@manakind/ui-core';
|
|
2
|
+
import type { ElementType } 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
|
+
/**
|
|
54
|
+
* One Manuia goal as a compact row, for the list view. Render it inside a
|
|
55
|
+
* `GoalList`: it is the `<li>`.
|
|
56
|
+
*
|
|
57
|
+
* Carries what `GoalCard` does where a row has room for it — title,
|
|
58
|
+
* timeframe and period, categories, a milestone count, target date and the
|
|
59
|
+
* status — and leaves out the description, the milestone checklist and the
|
|
60
|
+
* prestige-tier decoration. Behaves like the card: with an `href` the title is
|
|
61
|
+
* the link and its hit area stretches over the row, and the status menu sits
|
|
62
|
+
* above it, separately operable.
|
|
63
|
+
*
|
|
64
|
+
* Wide, the row reads left to right: title over its details, then categories,
|
|
65
|
+
* then status. Narrow, the categories drop below and the status stays beside
|
|
66
|
+
* the title.
|
|
67
|
+
*/
|
|
68
|
+
export declare function GoalListItem({ title, type, status, statusIcon, onStatusChange, statusMenuIndicator, statusMenuItemIndicator, periodLabel, categories, maxVisibleCategories, milestones, targetDate, typeIcon, href, linkComponent: LinkComponent, titleAs, className, }: GoalListItemProps): import("react/jsx-runtime").JSX.Element;
|
|
69
|
+
//# 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,MAAM,OAAO,CAAC;AACzC,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;CACpB;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,GACV,EAAE,iBAAiB,2CA8DnB"}
|
|
@@ -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, }) {
|
|
22
|
+
const completed = milestones?.filter((m) => m.completed).length ?? 0;
|
|
23
|
+
const total = milestones?.length ?? 0;
|
|
24
|
+
return (_jsx("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 })] }) }) }));
|
|
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;AAiD9B;;;;;;;;;;;;;;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,GACS;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,aAAI,SAAS,EAAE,EAAE,CAAC,oBAAoB,EAAE,SAAS,CAAC,YAChD,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,GACJ,CACN,CAAC;AACJ,CAAC"}
|
|
@@ -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 @@
|
|
|
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,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 @@
|
|
|
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 @@
|
|
|
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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.
|
|
3
|
+
"version": "0.7.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.
|
|
41
|
-
"@manakind/ui-core": "0.
|
|
40
|
+
"@manakind/manuia-tokens": "0.7.0",
|
|
41
|
+
"@manakind/ui-core": "0.7.0"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"react": "^19.0.0",
|