@cfasim-ui/docs 0.3.11

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 (60) hide show
  1. package/LICENSE +201 -0
  2. package/charts/ChartMenu/ChartMenu.vue +140 -0
  3. package/charts/ChartMenu/download.ts +44 -0
  4. package/charts/ChartTooltip/ChartTooltip.vue +97 -0
  5. package/charts/ChoroplethMap/ChoroplethMap.md +398 -0
  6. package/charts/ChoroplethMap/ChoroplethMap.vue +777 -0
  7. package/charts/ChoroplethMap/hsaMapping.ts +4116 -0
  8. package/charts/DataTable/DataTable.md +143 -0
  9. package/charts/DataTable/DataTable.vue +277 -0
  10. package/charts/LineChart/LineChart.md +472 -0
  11. package/charts/LineChart/LineChart.vue +1216 -0
  12. package/charts/index.ts +23 -0
  13. package/charts/tooltip-position.ts +49 -0
  14. package/components/Box/Box.md +49 -0
  15. package/components/Box/Box.vue +52 -0
  16. package/components/Button/Button.md +67 -0
  17. package/components/Button/Button.vue +81 -0
  18. package/components/Expander/Expander.md +34 -0
  19. package/components/Expander/Expander.vue +95 -0
  20. package/components/Hint/Hint.md +29 -0
  21. package/components/Hint/Hint.vue +83 -0
  22. package/components/Icon/Icon.md +67 -0
  23. package/components/Icon/Icon.vue +112 -0
  24. package/components/LightDarkToggle/LightDarkToggle.vue +49 -0
  25. package/components/NumberInput/NumberInput.md +305 -0
  26. package/components/NumberInput/NumberInput.vue +531 -0
  27. package/components/SelectBox/SelectBox.md +110 -0
  28. package/components/SelectBox/SelectBox.vue +195 -0
  29. package/components/SidebarLayout/SidebarLayout.md +104 -0
  30. package/components/SidebarLayout/SidebarLayout.vue +466 -0
  31. package/components/Spinner/Spinner.md +51 -0
  32. package/components/Spinner/Spinner.vue +55 -0
  33. package/components/TextInput/TextInput.md +82 -0
  34. package/components/TextInput/TextInput.vue +94 -0
  35. package/components/Toggle/Toggle.md +81 -0
  36. package/components/Toggle/Toggle.vue +81 -0
  37. package/components/index.ts +15 -0
  38. package/index.json +121 -0
  39. package/package.json +24 -0
  40. package/pyodide/index.ts +7 -0
  41. package/pyodide/pyodide.worker.ts +233 -0
  42. package/pyodide/pyodideWorkerApi.ts +102 -0
  43. package/pyodide/useModel.ts +86 -0
  44. package/pyodide/vitePlugin.js +51 -0
  45. package/shared/ModelOutput.ts +88 -0
  46. package/shared/csv.ts +22 -0
  47. package/shared/index.ts +24 -0
  48. package/shared/transferUtils.ts +126 -0
  49. package/shared/useUrlParams.ts +296 -0
  50. package/theme/all.js +5 -0
  51. package/theme/base.css +176 -0
  52. package/theme/cfasim.css +3 -0
  53. package/theme/theme.css +113 -0
  54. package/theme/themes/cdc.css +22 -0
  55. package/theme/utilities.css +518 -0
  56. package/wasm/index.ts +2 -0
  57. package/wasm/useModel.ts +53 -0
  58. package/wasm/vitePlugin.js +35 -0
  59. package/wasm/wasm.worker.ts +74 -0
  60. package/wasm/wasmWorkerApi.ts +38 -0
@@ -0,0 +1,23 @@
1
+ export {
2
+ default as LineChart,
3
+ type Series,
4
+ type Area,
5
+ type AreaSection,
6
+ } from "./LineChart/LineChart.vue";
7
+ export {
8
+ default as ChoroplethMap,
9
+ type GeoType,
10
+ type StateData,
11
+ type ChoroplethColorScale,
12
+ type ThresholdStop,
13
+ type CategoricalStop,
14
+ } from "./ChoroplethMap/ChoroplethMap.vue";
15
+ export { default as ChartTooltip } from "./ChartTooltip/ChartTooltip.vue";
16
+ export {
17
+ default as DataTable,
18
+ type TableData,
19
+ type TableRecord,
20
+ type ColumnAlign,
21
+ type ColumnConfig,
22
+ type ColumnWidth,
23
+ } from "./DataTable/DataTable.vue";
@@ -0,0 +1,49 @@
1
+ export type TooltipClamp = "none" | "chart" | "window";
2
+
3
+ const GAP = 16;
4
+ const PAD = 8;
5
+
6
+ /**
7
+ * Computes a tooltip position in client coordinates, flipping to the opposite
8
+ * side of the pointer and clamping vertically when the preferred placement
9
+ * would overflow the clamp boundary.
10
+ *
11
+ * The tooltip is assumed to be anchored with `transform: translateY(-50%)`,
12
+ * so `top` is the vertical center.
13
+ */
14
+ export function placeTooltip(
15
+ clientX: number,
16
+ centerY: number,
17
+ tipW: number,
18
+ tipH: number,
19
+ clamp: TooltipClamp,
20
+ chartRect?: DOMRect,
21
+ ): { left: number; top: number } {
22
+ if (clamp === "none") {
23
+ return { left: clientX + GAP, top: centerY };
24
+ }
25
+
26
+ const bounds =
27
+ clamp === "chart" && chartRect
28
+ ? {
29
+ left: chartRect.left,
30
+ right: chartRect.right,
31
+ top: chartRect.top,
32
+ bottom: chartRect.bottom,
33
+ }
34
+ : {
35
+ left: 0,
36
+ right: window.innerWidth,
37
+ top: 0,
38
+ bottom: window.innerHeight,
39
+ };
40
+
41
+ const flip = clientX + GAP + tipW > bounds.right - PAD;
42
+ const left = flip ? clientX - GAP - tipW : clientX + GAP;
43
+ const halfH = tipH / 2;
44
+ const top = Math.min(
45
+ Math.max(centerY, bounds.top + PAD + halfH),
46
+ bounds.bottom - PAD - halfH,
47
+ );
48
+ return { left, top };
49
+ }
@@ -0,0 +1,49 @@
1
+ # Box
2
+
3
+ A colored container for callouts, alerts, and grouped content.
4
+
5
+ ## Examples
6
+
7
+ ### Variants
8
+
9
+ <ComponentDemo>
10
+ <Box variant="info">This is an info box.</Box>
11
+ <Box variant="success">This is a success box.</Box>
12
+ <Box variant="warning">This is a warning box.</Box>
13
+ <Box variant="error">This is an error box.</Box>
14
+
15
+ <template #code>
16
+
17
+ ```vue
18
+ <Box variant="info">This is an info box.</Box>
19
+ <Box variant="success">This is a success box.</Box>
20
+ <Box variant="warning">This is a warning box.</Box>
21
+ <Box variant="error">This is an error box.</Box>
22
+ ```
23
+
24
+ </template>
25
+ </ComponentDemo>
26
+
27
+ ### Custom colors
28
+
29
+ <ComponentDemo>
30
+ <Box bg-color="#f0e6ff" text-color="#4a1d96">Custom purple box</Box>
31
+
32
+ <template #code>
33
+
34
+ ```vue
35
+ <Box bg-color="#f0e6ff" text-color="#4a1d96">Custom purple box</Box>
36
+ ```
37
+
38
+ </template>
39
+ </ComponentDemo>
40
+
41
+ ## Props
42
+
43
+ | Prop | Type | Required | Default |
44
+ |------|------|----------|---------|
45
+ | `variant` | `BoxVariant` | No | — |
46
+ | `bgColor` | `string` | No | — |
47
+ | `textColor` | `string` | No | — |
48
+ | `role` | `string` | No | — |
49
+
@@ -0,0 +1,52 @@
1
+ <script setup lang="ts">
2
+ export type BoxVariant = "info" | "success" | "warning" | "error";
3
+
4
+ defineProps<{
5
+ variant?: BoxVariant;
6
+ bgColor?: string;
7
+ textColor?: string;
8
+ role?: string;
9
+ }>();
10
+ </script>
11
+
12
+ <template>
13
+ <div
14
+ class="box"
15
+ :class="variant ? `box-${variant}` : undefined"
16
+ :style="{
17
+ backgroundColor: bgColor,
18
+ color: textColor,
19
+ }"
20
+ :role="role"
21
+ >
22
+ <slot />
23
+ </div>
24
+ </template>
25
+
26
+ <style scoped>
27
+ .box {
28
+ padding: 0.75em 1.25em;
29
+ border-radius: 0.375em;
30
+ font-size: var(--font-size-sm);
31
+ }
32
+
33
+ .box-info {
34
+ background-color: var(--color-box-info-bg);
35
+ color: var(--color-box-info-text);
36
+ }
37
+
38
+ .box-success {
39
+ background-color: var(--color-box-success-bg);
40
+ color: var(--color-box-success-text);
41
+ }
42
+
43
+ .box-warning {
44
+ background-color: var(--color-box-warning-bg);
45
+ color: var(--color-box-warning-text);
46
+ }
47
+
48
+ .box-error {
49
+ background-color: var(--color-box-error-bg);
50
+ color: var(--color-box-error-text);
51
+ }
52
+ </style>
@@ -0,0 +1,67 @@
1
+ # Button
2
+
3
+ A button for triggering actions. Supports primary and secondary variants.
4
+
5
+ Built on [reka-ui Primitive](https://reka-ui.com/docs/utilities/primitive), so it supports `as` and `asChild` for rendering as different elements.
6
+
7
+ ## Examples
8
+
9
+ ### Variants
10
+
11
+ <ComponentDemo>
12
+ <Button>Primary</Button>
13
+ <Button variant="secondary">Secondary</Button>
14
+
15
+ <template #code>
16
+
17
+ ```vue
18
+ <Button>Primary</Button>
19
+ <Button variant="secondary">Secondary</Button>
20
+ ```
21
+
22
+ </template>
23
+ </ComponentDemo>
24
+
25
+ ### Disabled
26
+
27
+ <ComponentDemo>
28
+ <Button disabled>Disabled</Button>
29
+ <Button variant="secondary" disabled>Disabled</Button>
30
+
31
+ <template #code>
32
+
33
+ ```vue
34
+ <Button disabled>Disabled</Button>
35
+ <Button variant="secondary" disabled>Disabled</Button>
36
+ ```
37
+
38
+ </template>
39
+ </ComponentDemo>
40
+
41
+ ### With label prop
42
+
43
+ <ComponentDemo>
44
+ <Button label="Click me" />
45
+
46
+ <template #code>
47
+
48
+ ```vue
49
+ <Button label="Click me" />
50
+ ```
51
+
52
+ </template>
53
+ </ComponentDemo>
54
+
55
+ ## Props
56
+
57
+ | Prop | Type | Required | Default |
58
+ |------|------|----------|---------|
59
+ | `label` | `string` | No | — |
60
+ | `variant` | `"primary" \| "secondary"` | No | `"primary"` |
61
+
62
+ ## Events
63
+
64
+ | Event | Payload |
65
+ |-------|---------|
66
+ | `click` | `event: MouseEvent` |
67
+
@@ -0,0 +1,81 @@
1
+ <script setup lang="ts">
2
+ import { Primitive } from "reka-ui";
3
+ import type { PrimitiveProps } from "reka-ui";
4
+
5
+ interface Props extends PrimitiveProps {
6
+ label?: string;
7
+ variant?: "primary" | "secondary";
8
+ }
9
+
10
+ withDefaults(defineProps<Props>(), {
11
+ as: "button",
12
+ variant: "primary",
13
+ });
14
+
15
+ defineEmits<{
16
+ click: [event: MouseEvent];
17
+ }>();
18
+ </script>
19
+
20
+ <template>
21
+ <Primitive
22
+ class="button"
23
+ :data-variant="variant"
24
+ :as="as"
25
+ :as-child="asChild"
26
+ @click="$emit('click', $event)"
27
+ >
28
+ <slot>{{ label }}</slot>
29
+ </Primitive>
30
+ </template>
31
+
32
+ <style scoped>
33
+ .button {
34
+ display: inline-flex;
35
+ border: none;
36
+ align-items: center;
37
+ justify-content: center;
38
+ align-self: flex-start;
39
+ flex-shrink: 0;
40
+ min-height: 2.5em;
41
+ padding: 0 1em;
42
+ font-size: var(--font-size-sm);
43
+ font-weight: 500;
44
+ border-radius: 0.375em;
45
+ background-color: var(--color-primary);
46
+ color: var(--color-text-on-primary);
47
+ }
48
+
49
+ .button:hover {
50
+ cursor: pointer;
51
+ background-color: var(--color-primary-hover);
52
+ }
53
+
54
+ .button:active {
55
+ background-color: var(--color-primary-active);
56
+ }
57
+
58
+ .button:focus-visible {
59
+ outline: none;
60
+ box-shadow: var(--shadow-focus);
61
+ }
62
+
63
+ .button:disabled {
64
+ opacity: 0.5;
65
+ cursor: not-allowed;
66
+ }
67
+
68
+ .button[data-variant="secondary"] {
69
+ background-color: transparent;
70
+ color: var(--color-primary);
71
+ border: 1px solid var(--color-primary);
72
+ }
73
+
74
+ .button[data-variant="secondary"]:hover {
75
+ background-color: color-mix(in srgb, var(--color-primary) 10%, transparent);
76
+ }
77
+
78
+ .button[data-variant="secondary"]:active {
79
+ background-color: color-mix(in srgb, var(--color-primary) 15%, transparent);
80
+ }
81
+ </style>
@@ -0,0 +1,34 @@
1
+ # Expander
2
+
3
+ A collapsible section that toggles content visibility.
4
+
5
+ ## Examples
6
+
7
+ <ComponentDemo>
8
+ <Expander label="Show advanced options">
9
+ <p style="margin: 0">Here is the hidden content.</p>
10
+ </Expander>
11
+
12
+ <template #code>
13
+
14
+ ```vue
15
+ <Expander label="Show advanced options">
16
+ <p>Here is the hidden content.</p>
17
+ </Expander>
18
+ ```
19
+
20
+ </template>
21
+ </ComponentDemo>
22
+
23
+ ## Model
24
+
25
+ | Name | Type |
26
+ |------|------|
27
+ | `v-model:open` | `boolean` |
28
+
29
+ ## Props
30
+
31
+ | Prop | Type | Required | Default |
32
+ |------|------|----------|---------|
33
+ | `label` | `string` | No | — |
34
+
@@ -0,0 +1,95 @@
1
+ <script setup lang="ts">
2
+ import {
3
+ CollapsibleRoot,
4
+ CollapsibleTrigger,
5
+ CollapsibleContent,
6
+ } from "reka-ui";
7
+
8
+ const open = defineModel<boolean>("open", { default: false });
9
+
10
+ defineProps<{
11
+ label?: string;
12
+ }>();
13
+ </script>
14
+
15
+ <template>
16
+ <CollapsibleRoot v-model:open="open" class="expander">
17
+ <CollapsibleTrigger class="expander-trigger">
18
+ <span class="expander-caret" :class="{ open }" />
19
+ <slot name="label">{{ label }}</slot>
20
+ </CollapsibleTrigger>
21
+ <CollapsibleContent class="expander-content">
22
+ <slot />
23
+ </CollapsibleContent>
24
+ </CollapsibleRoot>
25
+ </template>
26
+
27
+ <style scoped>
28
+ .expander-trigger {
29
+ display: flex;
30
+ align-items: center;
31
+ gap: 0.5em;
32
+ width: 100%;
33
+ padding: 0.5em 0;
34
+ background: none;
35
+ border: none;
36
+ cursor: pointer;
37
+ font: inherit;
38
+ font-size: var(--font-size-sm);
39
+ font-weight: 600;
40
+ text-transform: uppercase;
41
+ letter-spacing: 0.05em;
42
+ color: var(--color-text-secondary);
43
+ }
44
+
45
+ .expander-trigger:hover {
46
+ color: var(--color-text);
47
+ }
48
+
49
+ .expander-caret {
50
+ display: inline-block;
51
+ width: 0;
52
+ height: 0;
53
+ border-left: 0.35em solid currentColor;
54
+ border-top: 0.3em solid transparent;
55
+ border-bottom: 0.3em solid transparent;
56
+ transition: transform 0.15s;
57
+ }
58
+
59
+ .expander-caret.open {
60
+ transform: rotate(90deg);
61
+ }
62
+
63
+ .expander-content {
64
+ overflow: hidden;
65
+ display: flex;
66
+ flex-direction: column;
67
+ gap: 0.75em;
68
+ }
69
+
70
+ .expander-content[data-state="open"] {
71
+ animation: slideDown 200ms ease-out;
72
+ }
73
+
74
+ .expander-content[data-state="closed"] {
75
+ animation: slideUp 200ms ease-out;
76
+ }
77
+
78
+ @keyframes slideDown {
79
+ from {
80
+ height: 0;
81
+ }
82
+ to {
83
+ height: var(--reka-collapsible-content-height);
84
+ }
85
+ }
86
+
87
+ @keyframes slideUp {
88
+ from {
89
+ height: var(--reka-collapsible-content-height);
90
+ }
91
+ to {
92
+ height: 0;
93
+ }
94
+ }
95
+ </style>
@@ -0,0 +1,29 @@
1
+ # Hint
2
+
3
+ An info icon that shows a tooltip on hover. Used alongside form labels to provide additional context.
4
+
5
+ ## Examples
6
+
7
+ <ComponentDemo>
8
+ <span style="display: flex; align-items: center; gap: 8px;">
9
+ Population size <Hint text="The total number of individuals in the simulation." />
10
+ </span>
11
+
12
+ <template #code>
13
+
14
+ ```vue
15
+ <span style="display: flex; align-items: center; gap: 8px;">
16
+ Population size
17
+ <Hint text="The total number of individuals in the simulation." />
18
+ </span>
19
+ ```
20
+
21
+ </template>
22
+ </ComponentDemo>
23
+
24
+ ## Props
25
+
26
+ | Prop | Type | Required | Default |
27
+ |------|------|----------|---------|
28
+ | `text` | `string` | Yes | — |
29
+
@@ -0,0 +1,83 @@
1
+ <script setup lang="ts">
2
+ import {
3
+ TooltipArrow,
4
+ TooltipContent,
5
+ TooltipPortal,
6
+ TooltipProvider,
7
+ TooltipRoot,
8
+ TooltipTrigger,
9
+ } from "reka-ui";
10
+ import Icon from "../Icon/Icon.vue";
11
+
12
+ defineProps<{
13
+ text: string;
14
+ }>();
15
+ </script>
16
+
17
+ <template>
18
+ <TooltipProvider>
19
+ <TooltipRoot :delay-duration="0" disable-closing-trigger>
20
+ <TooltipTrigger as-child>
21
+ <button
22
+ type="button"
23
+ class="HintTrigger"
24
+ aria-label="More info"
25
+ @pointerdown.prevent
26
+ >
27
+ <Icon icon="help" :size="16" />
28
+ </button>
29
+ </TooltipTrigger>
30
+ <TooltipPortal>
31
+ <TooltipContent class="HintContent" side="top" :side-offset="4">
32
+ {{ text }}
33
+ <TooltipArrow class="HintArrow" :width="10" :height="5" />
34
+ </TooltipContent>
35
+ </TooltipPortal>
36
+ </TooltipRoot>
37
+ </TooltipProvider>
38
+ </template>
39
+
40
+ <style scoped>
41
+ .HintTrigger {
42
+ display: inline-flex;
43
+ align-items: center;
44
+ justify-content: center;
45
+ width: 1.25em;
46
+ height: 1.25em;
47
+ padding: 0;
48
+ margin: 0;
49
+ border: none;
50
+ border-radius: 50%;
51
+ background: transparent;
52
+ color: var(--color-text-secondary);
53
+ cursor: pointer;
54
+ flex-shrink: 0;
55
+ }
56
+
57
+ .HintTrigger:hover {
58
+ color: var(--color-text);
59
+ }
60
+
61
+ .HintTrigger:focus-visible {
62
+ outline: none;
63
+ box-shadow: var(--shadow-focus);
64
+ }
65
+ </style>
66
+
67
+ <style>
68
+ .HintContent {
69
+ max-width: 15rem;
70
+ padding: 0.5em 0.75em;
71
+ font-size: var(--font-size-xs);
72
+ line-height: 1.4;
73
+ color: var(--color-bg-0);
74
+ background-color: var(--color-text);
75
+ border-radius: 0.25em;
76
+ box-shadow: var(--shadow-md);
77
+ z-index: 100;
78
+ }
79
+
80
+ .HintArrow {
81
+ fill: var(--color-text);
82
+ }
83
+ </style>
@@ -0,0 +1,67 @@
1
+ # Icon
2
+
3
+ Renders a [Material Symbols Outlined](https://fonts.google.com/icons) icon.
4
+
5
+ ## Examples
6
+
7
+ ### Sizes
8
+
9
+ <ComponentDemo>
10
+ <Icon icon="help" size="sm" aria-label="help" />
11
+ <Icon icon="help" size="md" aria-label="help" />
12
+ <Icon icon="help" size="lg" aria-label="help" />
13
+
14
+ <template #code>
15
+
16
+ ```vue
17
+ <Icon icon="help" size="sm" aria-label="help" />
18
+ <Icon icon="help" size="md" aria-label="help" />
19
+ <Icon icon="help" size="lg" aria-label="help" />
20
+ ```
21
+
22
+ </template>
23
+ </ComponentDemo>
24
+
25
+ ### Filled
26
+
27
+ <ComponentDemo>
28
+ <Icon icon="favorite" size="lg" aria-label="favorite" />
29
+ <Icon icon="favorite" size="lg" :fill="true" aria-label="favorite filled" />
30
+
31
+ <template #code>
32
+
33
+ ```vue
34
+ <Icon icon="favorite" size="lg" aria-label="favorite" />
35
+ <Icon icon="favorite" size="lg" :fill="true" aria-label="favorite filled" />
36
+ ```
37
+
38
+ </template>
39
+ </ComponentDemo>
40
+
41
+ ### Inline in text
42
+
43
+ <ComponentDemo>
44
+ <p style="margin: 0">Click the <Icon icon="help" size="sm" :inline="true" aria-label="help" /> icon for more info.</p>
45
+
46
+ <template #code>
47
+
48
+ ```vue
49
+ <p>Click the <Icon icon="help" size="sm" :inline="true" aria-label="help" /> icon for more info.</p>
50
+ ```
51
+
52
+ </template>
53
+ </ComponentDemo>
54
+
55
+ ## Props
56
+
57
+ | Prop | Type | Required | Default |
58
+ |------|------|----------|---------|
59
+ | `icon` | `string` | Yes | — |
60
+ | `size` | `IconSize \| number` | No | `"md"` |
61
+ | `fill` | `boolean` | No | `false` |
62
+ | `weight` | `number` | No | — |
63
+ | `grade` | `number` | No | — |
64
+ | `decorative` | `boolean` | No | `true` |
65
+ | `ariaLabel` | `string` | No | — |
66
+ | `inline` | `boolean` | No | `false` |
67
+