@onereach/idw-ui-components 0.1.2-beta.7.0 → 0.2.0-beta.27.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/README.md +360 -1
- package/dist/cjs/index.js +2 -18
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +1639 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/idw-ui-components.css +1 -0
- package/dist/types/components/Feeds/FeedEmbed/FeedEmbed.vue.d.ts +16 -0
- package/dist/types/components/Feeds/FeedEmbed/FeedEmbed.vue.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedFileContent/FeedFileContent.vue.d.ts +6 -0
- package/dist/types/components/Feeds/FeedFileContent/FeedFileContent.vue.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedFileContent/index.d.ts +3 -0
- package/dist/types/components/Feeds/FeedFileContent/index.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedFileContent/types.d.ts +13 -0
- package/dist/types/components/Feeds/FeedFileContent/types.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedHtmlContent/FeedHtmlContent.vue.d.ts +6 -0
- package/dist/types/components/Feeds/FeedHtmlContent/FeedHtmlContent.vue.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedHtmlContent/index.d.ts +3 -0
- package/dist/types/components/Feeds/FeedHtmlContent/index.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedHtmlContent/types.d.ts +13 -0
- package/dist/types/components/Feeds/FeedHtmlContent/types.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedItemBase/FeedItemBase.vue.d.ts +42 -0
- package/dist/types/components/Feeds/FeedItemBase/FeedItemBase.vue.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedItemBase/index.d.ts +3 -0
- package/dist/types/components/Feeds/FeedItemBase/index.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedItemBase/types.d.ts +35 -0
- package/dist/types/components/Feeds/FeedItemBase/types.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedItemMetaFooter/FeedItemMetaFooter.vue.d.ts +12 -0
- package/dist/types/components/Feeds/FeedItemMetaFooter/FeedItemMetaFooter.vue.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedItemMetaFooter/index.d.ts +3 -0
- package/dist/types/components/Feeds/FeedItemMetaFooter/index.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedItemMetaFooter/types.d.ts +27 -0
- package/dist/types/components/Feeds/FeedItemMetaFooter/types.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedList/FeedList.vue.d.ts +60 -0
- package/dist/types/components/Feeds/FeedList/FeedList.vue.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedList/FeedListItemBody.vue.d.ts +17 -0
- package/dist/types/components/Feeds/FeedList/FeedListItemBody.vue.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedList/index.d.ts +3 -0
- package/dist/types/components/Feeds/FeedList/index.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedList/types.d.ts +69 -0
- package/dist/types/components/Feeds/FeedList/types.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedMarkdownContent/FeedMarkdownContent.vue.d.ts +7 -0
- package/dist/types/components/Feeds/FeedMarkdownContent/FeedMarkdownContent.vue.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedMarkdownContent/index.d.ts +3 -0
- package/dist/types/components/Feeds/FeedMarkdownContent/index.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedMarkdownContent/types.d.ts +12 -0
- package/dist/types/components/Feeds/FeedMarkdownContent/types.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedSkillContent/FeedSkillContent.vue.d.ts +29 -0
- package/dist/types/components/Feeds/FeedSkillContent/FeedSkillContent.vue.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedSkillContent/index.d.ts +3 -0
- package/dist/types/components/Feeds/FeedSkillContent/index.d.ts.map +1 -0
- package/dist/types/components/Feeds/FeedSkillContent/types.d.ts +29 -0
- package/dist/types/components/Feeds/FeedSkillContent/types.d.ts.map +1 -0
- package/dist/types/components/Feeds/feedEmbed.d.ts +10 -0
- package/dist/types/components/Feeds/feedEmbed.d.ts.map +1 -0
- package/dist/types/components/Feeds/formatFeedReadingTime.d.ts +3 -0
- package/dist/types/components/Feeds/formatFeedReadingTime.d.ts.map +1 -0
- package/dist/types/components/Feeds/index.d.ts +10 -0
- package/dist/types/components/Feeds/index.d.ts.map +1 -0
- package/dist/types/components/SkillCard/SkillCard.vue.d.ts +20 -0
- package/dist/types/components/SkillCard/SkillCard.vue.d.ts.map +1 -0
- package/dist/types/components/SkillCard/index.d.ts +4 -0
- package/dist/types/components/SkillCard/index.d.ts.map +1 -0
- package/dist/types/components/SkillCard/types.d.ts +17 -0
- package/dist/types/components/SkillCard/types.d.ts.map +1 -0
- package/dist/types/idw-card/bind/bindIdwCard.d.ts +7 -0
- package/dist/types/idw-card/bind/bindIdwCard.d.ts.map +1 -0
- package/dist/types/idw-card/bind/index.d.ts +2 -0
- package/dist/types/idw-card/bind/index.d.ts.map +1 -0
- package/dist/types/idw-card/form/dates.d.ts +5 -0
- package/dist/types/idw-card/form/dates.d.ts.map +1 -0
- package/dist/types/idw-card/form/formContext.d.ts +10 -0
- package/dist/types/idw-card/form/formContext.d.ts.map +1 -0
- package/dist/types/idw-card/form/index.d.ts +3 -0
- package/dist/types/idw-card/form/index.d.ts.map +1 -0
- package/dist/types/idw-card/host/hostConfig.d.ts +13 -0
- package/dist/types/idw-card/host/hostConfig.d.ts.map +1 -0
- package/dist/types/idw-card/host/index.d.ts +3 -0
- package/dist/types/idw-card/host/index.d.ts.map +1 -0
- package/dist/types/idw-card/index.d.ts +10 -0
- package/dist/types/idw-card/index.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/CardRenderer.vue.d.ts +18 -0
- package/dist/types/idw-card/renderer/CardRenderer.vue.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/IdwCardActionBar.vue.d.ts +12 -0
- package/dist/types/idw-card/renderer/IdwCardActionBar.vue.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/IdwCardElementView.vue.d.ts +16 -0
- package/dist/types/idw-card/renderer/IdwCardElementView.vue.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/actionStyle.d.ts +12 -0
- package/dist/types/idw-card/renderer/actionStyle.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/elements/ActionSetElement.vue.d.ts +12 -0
- package/dist/types/idw-card/renderer/elements/ActionSetElement.vue.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/elements/BadgeElement.vue.d.ts +7 -0
- package/dist/types/idw-card/renderer/elements/BadgeElement.vue.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/elements/ColumnSetElement.vue.d.ts +16 -0
- package/dist/types/idw-card/renderer/elements/ColumnSetElement.vue.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/elements/ContainerElement.vue.d.ts +16 -0
- package/dist/types/idw-card/renderer/elements/ContainerElement.vue.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/elements/FactSetElement.vue.d.ts +7 -0
- package/dist/types/idw-card/renderer/elements/FactSetElement.vue.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/elements/FileElement.vue.d.ts +9 -0
- package/dist/types/idw-card/renderer/elements/FileElement.vue.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/elements/HtmlElement.vue.d.ts +9 -0
- package/dist/types/idw-card/renderer/elements/HtmlElement.vue.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/elements/IconElement.vue.d.ts +7 -0
- package/dist/types/idw-card/renderer/elements/IconElement.vue.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/elements/ImageElement.vue.d.ts +7 -0
- package/dist/types/idw-card/renderer/elements/ImageElement.vue.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/elements/ImageSetElement.vue.d.ts +7 -0
- package/dist/types/idw-card/renderer/elements/ImageSetElement.vue.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/elements/InputElement.vue.d.ts +7 -0
- package/dist/types/idw-card/renderer/elements/InputElement.vue.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/elements/MediaElement.vue.d.ts +7 -0
- package/dist/types/idw-card/renderer/elements/MediaElement.vue.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/elements/ProgressElement.vue.d.ts +7 -0
- package/dist/types/idw-card/renderer/elements/ProgressElement.vue.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/elements/SkillElement.vue.d.ts +14 -0
- package/dist/types/idw-card/renderer/elements/SkillElement.vue.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/elements/TableElement.vue.d.ts +7 -0
- package/dist/types/idw-card/renderer/elements/TableElement.vue.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/elements/TextElement.vue.d.ts +7 -0
- package/dist/types/idw-card/renderer/elements/TextElement.vue.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/index.d.ts +3 -0
- package/dist/types/idw-card/renderer/index.d.ts.map +1 -0
- package/dist/types/idw-card/renderer/types.d.ts +12 -0
- package/dist/types/idw-card/renderer/types.d.ts.map +1 -0
- package/dist/types/idw-card/schema/index.d.ts +3 -0
- package/dist/types/idw-card/schema/index.d.ts.map +1 -0
- package/dist/types/idw-card/templates/approval.d.ts +94 -0
- package/dist/types/idw-card/templates/approval.d.ts.map +1 -0
- package/dist/types/idw-card/templates/compile.d.ts +7 -0
- package/dist/types/idw-card/templates/compile.d.ts.map +1 -0
- package/dist/types/idw-card/templates/index.d.ts +7 -0
- package/dist/types/idw-card/templates/index.d.ts.map +1 -0
- package/dist/types/idw-card/templates/registry.d.ts +16 -0
- package/dist/types/idw-card/templates/registry.d.ts.map +1 -0
- package/dist/types/idw-card/templates/types.d.ts +20 -0
- package/dist/types/idw-card/templates/types.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +33 -14
- package/dist/cjs/format-idw-summary.js +0 -11
- package/dist/cjs/format-idw-summary.js.map +0 -1
- package/dist/esm/format-idw-summary.js +0 -8
- package/dist/esm/format-idw-summary.js.map +0 -1
package/README.md
CHANGED
|
@@ -2,13 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
> Shared IDW UI components and browser helpers. Consumed by `idw-ui`.
|
|
4
4
|
|
|
5
|
+
Peer dependencies:
|
|
6
|
+
|
|
7
|
+
- `vue` ^3.5
|
|
8
|
+
- `@onereach/ui-components` >= 26.14
|
|
9
|
+
- `@onereach/idw-markdown-renderer` >= 1.1 (used by `FeedMarkdownContent` / `FeedSkillContent`)
|
|
10
|
+
|
|
11
|
+
The host app must load Onereach styles / Tailwind (`@onereach/styles`) so utility classes and design tokens resolve. Include this package in the host Tailwind `content` globs (for example `./node_modules/@onereach/idw-ui-components/dist/**/*.{js,mjs,cjs}`) so class names used by components are not purged.
|
|
12
|
+
|
|
5
13
|
## Installation
|
|
6
14
|
|
|
7
15
|
```bash
|
|
8
16
|
pnpm add @onereach/idw-ui-components
|
|
9
17
|
```
|
|
10
18
|
|
|
11
|
-
##
|
|
19
|
+
## Helpers
|
|
12
20
|
|
|
13
21
|
```typescript
|
|
14
22
|
import { formatIdwSummary } from '@onereach/idw-ui-components';
|
|
@@ -16,3 +24,354 @@ import type { IdwSummary } from '@onereach/idw-contracts';
|
|
|
16
24
|
|
|
17
25
|
const label = formatIdwSummary(summary satisfies IdwSummary);
|
|
18
26
|
```
|
|
27
|
+
|
|
28
|
+
## SkillCard
|
|
29
|
+
|
|
30
|
+
Presentational skill tile (sizes `xs` / `s` / `l`). Used by feeds and settings surfaces.
|
|
31
|
+
|
|
32
|
+
```vue
|
|
33
|
+
<script setup lang="ts">
|
|
34
|
+
import { CardSize, SkillCard, type SkillCardData } from '@onereach/idw-ui-components';
|
|
35
|
+
|
|
36
|
+
const skill = {
|
|
37
|
+
id: '1',
|
|
38
|
+
name: 'Vacation',
|
|
39
|
+
image: '/skill.png',
|
|
40
|
+
domain: 'HR',
|
|
41
|
+
} satisfies SkillCardData;
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<template>
|
|
45
|
+
<SkillCard
|
|
46
|
+
:skill="skill"
|
|
47
|
+
:size="CardSize.S"
|
|
48
|
+
@click="onOpen"
|
|
49
|
+
/>
|
|
50
|
+
</template>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## FeedItemBase
|
|
54
|
+
|
|
55
|
+
Presentational shell for schema-driven feed items. It owns metadata, title, short description, feed-level controls, and expand/collapse. Body content is opaque via slots.
|
|
56
|
+
|
|
57
|
+
```vue
|
|
58
|
+
<script setup lang="ts">
|
|
59
|
+
import { FeedItemBase } from '@onereach/idw-ui-components';
|
|
60
|
+
</script>
|
|
61
|
+
|
|
62
|
+
<template>
|
|
63
|
+
<FeedItemBase
|
|
64
|
+
id="feed-1"
|
|
65
|
+
title="Important meeting needs review"
|
|
66
|
+
short-content="Owner Strategy Review overlaps with your vacation."
|
|
67
|
+
timestamp="1 min ago"
|
|
68
|
+
timestamp-datetime="2026-08-07T12:00:00.000Z"
|
|
69
|
+
source="by Vacation Skill"
|
|
70
|
+
>
|
|
71
|
+
<template #body>
|
|
72
|
+
<!-- Markdown, HTML, skill body, or embedded app -->
|
|
73
|
+
</template>
|
|
74
|
+
|
|
75
|
+
<template #actions>
|
|
76
|
+
<!-- Domain actions such as Approve or Reschedule -->
|
|
77
|
+
</template>
|
|
78
|
+
|
|
79
|
+
<template #footer>
|
|
80
|
+
<!-- Optional feedback, comments, or additional context (shown while body is open) -->
|
|
81
|
+
</template>
|
|
82
|
+
</FeedItemBase>
|
|
83
|
+
</template>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Props
|
|
87
|
+
|
|
88
|
+
| Prop | Type | Default | Description |
|
|
89
|
+
|------|------|---------|-------------|
|
|
90
|
+
| `id` | `string` | — | Stable feed item id (used for a11y ids) |
|
|
91
|
+
| `title` | `string` | — | Shell title (always visible) |
|
|
92
|
+
| `shortContent` | `string` | — | Shell short description |
|
|
93
|
+
| `timestamp` | `string` | — | Preformatted timestamp text |
|
|
94
|
+
| `timestampDatetime` | `string` | — | Optional value for `<time datetime>` |
|
|
95
|
+
| `source` | `string` | — | Source / author text |
|
|
96
|
+
| `expandable` | `boolean` | `true` | Whether the expand control is shown |
|
|
97
|
+
| `fullscreenControl` | `boolean` | `false` | Shows `open_in_full` inside default `#controls`; host owns overlay via `fullscreen` |
|
|
98
|
+
| `mentionControl` | `boolean` | `true` | Shows `alternate_email` (mention) inside default `#controls` |
|
|
99
|
+
| `isNew` | `boolean` | `false` | Attention shell (`primary-opacity-12`) vs settled shell (`surface-2`) |
|
|
100
|
+
| `controlLabels` | `Partial<Record<FeedItemControl, string>> & { fullscreen?: string }` | Mention / Fullscreen | Optional localized tooltips |
|
|
101
|
+
|
|
102
|
+
When `expandable` is `false`, the body is always shown and the expand button is hidden.
|
|
103
|
+
|
|
104
|
+
Expand labels are fixed (`Show more` / `Show less`). The scrollable body uses `max-height: 37.875rem` by default.
|
|
105
|
+
|
|
106
|
+
`FeedItemControl`: `'mention'`
|
|
107
|
+
|
|
108
|
+
### Slots
|
|
109
|
+
|
|
110
|
+
- `body` — rich / schema / app content (lazy-mounted on first expand, kept mounted while the item lives)
|
|
111
|
+
- `actions` — domain action buttons (visible only while body is open; empty slot content is hidden)
|
|
112
|
+
- `footer` — optional extra footer (visible only while body is open)
|
|
113
|
+
- `controls` — override default controls entirely (including fullscreen when `fullscreenControl` is true)
|
|
114
|
+
|
|
115
|
+
### Default controls
|
|
116
|
+
|
|
117
|
+
The default `#controls` content includes mention (`alternate_email`) when `mentionControl` is true (default), and fullscreen when `fullscreenControl` is true. A custom `#controls` slot replaces both.
|
|
118
|
+
|
|
119
|
+
```vue
|
|
120
|
+
<!-- Localize built-in control tooltips -->
|
|
121
|
+
<FeedItemBase
|
|
122
|
+
...
|
|
123
|
+
:control-labels="{ mention: 'Згадати', fullscreen: 'На весь екран' }"
|
|
124
|
+
/>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Events
|
|
128
|
+
|
|
129
|
+
- `update:expanded` — expanded state changed
|
|
130
|
+
- `expand` / `collapse` — convenience events
|
|
131
|
+
- `control-click` — `'mention'` from the default mention control
|
|
132
|
+
- `fullscreen` — fullscreen control clicked; host should open its overlay (modal / route)
|
|
133
|
+
|
|
134
|
+
### Body lifecycle
|
|
135
|
+
|
|
136
|
+
The body slot mounts on the first expansion and stays mounted afterwards. Collapsing hides it with `v-show` so embedded apps / iframes are not destroyed automatically.
|
|
137
|
+
|
|
138
|
+
## Feed type content (body slot)
|
|
139
|
+
|
|
140
|
+
Four presentational bodies for feed types (`markdown` | `skill` | `html` | `file`). Use them inside `FeedItemBase` `#body`. `FeedMarkdownContent` / `FeedSkillContent` encapsulate `@onereach/idw-markdown-renderer` plus feed `styled-content` typography. `FeedSkillContent` renders the built-in `SkillCard` when `skill` is passed (optional `#skill` override remains for rare custom cards).
|
|
141
|
+
|
|
142
|
+
```vue
|
|
143
|
+
<script setup lang="ts">
|
|
144
|
+
import {
|
|
145
|
+
FeedItemBase,
|
|
146
|
+
FeedMarkdownContent,
|
|
147
|
+
FeedSkillContent,
|
|
148
|
+
FeedHtmlContent,
|
|
149
|
+
FeedFileContent,
|
|
150
|
+
type SkillCardData,
|
|
151
|
+
} from '@onereach/idw-ui-components';
|
|
152
|
+
|
|
153
|
+
const skill = { id: '1', name: 'Vacation', image: '/s.png', domain: 'HR' } satisfies SkillCardData;
|
|
154
|
+
</script>
|
|
155
|
+
|
|
156
|
+
<template>
|
|
157
|
+
<FeedItemBase id="1" title="Markdown" short-content="…">
|
|
158
|
+
<template #body>
|
|
159
|
+
<FeedMarkdownContent :text="content" />
|
|
160
|
+
</template>
|
|
161
|
+
</FeedItemBase>
|
|
162
|
+
|
|
163
|
+
<FeedItemBase id="2" title="Skill" short-content="…">
|
|
164
|
+
<template #body>
|
|
165
|
+
<FeedSkillContent
|
|
166
|
+
:text="content"
|
|
167
|
+
:skill="skill"
|
|
168
|
+
start-skill-label="Open Skill"
|
|
169
|
+
@start-skill="onStartSkill"
|
|
170
|
+
@skill-click="onSkillClick"
|
|
171
|
+
/>
|
|
172
|
+
</template>
|
|
173
|
+
</FeedItemBase>
|
|
174
|
+
|
|
175
|
+
<FeedItemBase id="3" title="HTML" :fullscreen-control="true" class="[&_.feed-item-base__body]:!max-h-none">
|
|
176
|
+
<template #body>
|
|
177
|
+
<FeedHtmlContent title="HTML" :content="html" />
|
|
178
|
+
</template>
|
|
179
|
+
</FeedItemBase>
|
|
180
|
+
|
|
181
|
+
<FeedItemBase id="4" title="File" :fullscreen-control="true" class="[&_.feed-item-base__body]:!max-h-none">
|
|
182
|
+
<template #body>
|
|
183
|
+
<FeedFileContent title="File" :src="fileUrl" />
|
|
184
|
+
</template>
|
|
185
|
+
</FeedItemBase>
|
|
186
|
+
</template>
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
| Component | Feed type | Notes |
|
|
190
|
+
|-----------|-----------|--------|
|
|
191
|
+
| `FeedMarkdownContent` | `markdown` | Renders `text` via `OrWebMarkdownRender` + `styled-content` / body typography |
|
|
192
|
+
| `FeedSkillContent` | `skill` | Built-in `SkillCard` via `skill` prop + markdown; optional `startSkillLabel` → `start-skill`; `skill-click` |
|
|
193
|
+
| `FeedHtmlContent` | `html` | `srcdoc` iframe using the fixed `FEED_EMBED_SANDBOX`; `size`: `'list'` \| `'fill'` |
|
|
194
|
+
| `FeedFileContent` | `file` | `src` iframe using the fixed `FEED_EMBED_SANDBOX`; same `size` prop |
|
|
195
|
+
|
|
196
|
+
Shared helpers: `FEED_EMBED_SANDBOX`, `FEED_EMBED_SIZE_CLASS`, type `FeedEmbedSize`. The sandbox value is not configurable through component props. Html/file share an internal embed implementation; empty `src` / `srcdoc` renders nothing.
|
|
197
|
+
|
|
198
|
+
## FeedList
|
|
199
|
+
|
|
200
|
+
Scrollable list of discriminated `FeedListItem` rows. Each row is a `FeedItemBase` shell with the matching type body. Host owns data fetching, i18n, fullscreen modal, and list footer content (e.g. reactions / comments). Skill cards are rendered inside the toolkit when `item.skill` is set.
|
|
201
|
+
|
|
202
|
+
```vue
|
|
203
|
+
<script setup lang="ts">
|
|
204
|
+
import { FeedList, type FeedListItem } from '@onereach/idw-ui-components';
|
|
205
|
+
|
|
206
|
+
const items: FeedListItem[] = [
|
|
207
|
+
{ id: '1', title: 'Hello', type: 'markdown', content: '**Hi**', shortContent: 'Preview' },
|
|
208
|
+
{ id: '2', title: 'App', type: 'html', content: '<h1>App</h1>' },
|
|
209
|
+
{ id: '3', title: 'Doc', type: 'file', fileUrl: 'https://example.com/a.html' },
|
|
210
|
+
{
|
|
211
|
+
id: '4',
|
|
212
|
+
title: 'Skill news',
|
|
213
|
+
type: 'skill',
|
|
214
|
+
content: 'Details…',
|
|
215
|
+
skillId: 'skill-1',
|
|
216
|
+
skill: { id: 'skill-1', name: 'Vacation', image: '/s.png', domain: 'HR' },
|
|
217
|
+
startSkillLabel: 'Open Skill',
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
id: '5',
|
|
221
|
+
title: 'Approval',
|
|
222
|
+
type: 'card',
|
|
223
|
+
source: {
|
|
224
|
+
templateId: 'approval',
|
|
225
|
+
data: { title: 'Time off', summary: 'Approve vacation.', requester: 'Ada' },
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
];
|
|
229
|
+
</script>
|
|
230
|
+
|
|
231
|
+
<template>
|
|
232
|
+
<FeedList
|
|
233
|
+
class="h-full"
|
|
234
|
+
:items="items"
|
|
235
|
+
:loading="false"
|
|
236
|
+
:loading-more="false"
|
|
237
|
+
empty-label="No posts yet"
|
|
238
|
+
item-class="mx-md"
|
|
239
|
+
:control-labels="{ fullscreen: 'Open in fullscreen' }"
|
|
240
|
+
@reach-bottom="loadMore"
|
|
241
|
+
@fullscreen="openFullscreen"
|
|
242
|
+
@start-skill="openSkill"
|
|
243
|
+
@skill-click="openSkillOverview"
|
|
244
|
+
@action="onCardAction"
|
|
245
|
+
>
|
|
246
|
+
<template #header>
|
|
247
|
+
<!-- Optional host header -->
|
|
248
|
+
</template>
|
|
249
|
+
|
|
250
|
+
<template #footer="{ item }">
|
|
251
|
+
<!-- Host reactions / comments (shown only while expanded) -->
|
|
252
|
+
</template>
|
|
253
|
+
</FeedList>
|
|
254
|
+
</template>
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Props
|
|
258
|
+
|
|
259
|
+
| Prop | Type | Default | Description |
|
|
260
|
+
|------|------|---------|-------------|
|
|
261
|
+
| `items` | `FeedListItem[]` | — | Discriminated rows to render |
|
|
262
|
+
| `loading` | `boolean` | `false` | Replaces the list with a loader |
|
|
263
|
+
| `loadingMore` | `boolean` | `false` | Footer loader under existing items |
|
|
264
|
+
| `emptyLabel` | `string` | `No posts yet` | Shown when `items` is empty (unless `#empty`) |
|
|
265
|
+
| `controlLabels` | `FeedItemControlLabels` | — | Shared shell control tooltips |
|
|
266
|
+
| `reachBottomOffset` | `number` | `500` | Px from bottom; `reach-bottom` is edge-triggered |
|
|
267
|
+
| `itemClass` | `string` | — | Extra class on each `FeedItemBase` |
|
|
268
|
+
| `cardHostConfig` | `Partial<IdwCardHostConfig>` | — | Theme / embed size for `type: 'card'` rows |
|
|
269
|
+
|
|
270
|
+
`FeedListItem` is a discriminated union on `type`:
|
|
271
|
+
|
|
272
|
+
- `markdown` / `html` — require `content: string`
|
|
273
|
+
- `skill` — requires `content: string`; optional `skill` (`SkillCardData`) for the built-in card
|
|
274
|
+
- `file` — requires `fileUrl: string`
|
|
275
|
+
- `card` — requires `source` (`{ card }` or `{ templateId, data }`). Do not add `approval` / `task` as extra `type`s.
|
|
276
|
+
- Shell fields are picked from `FeedItemBaseProps` (`timestampDatetime`, `fullscreenControl`, `mentionControl`, `isNew`, …)
|
|
277
|
+
- Optional `engagement` (`FeedItemEngagement`) drives the built-in meta footer (reactions / comments / reading time) at the end of an **expanded** item
|
|
278
|
+
|
|
279
|
+
HTML/file rows get `fullscreenControl` by default and an unconstrained body max-height.
|
|
280
|
+
`mentionControl` defaults to `true` when omitted.
|
|
281
|
+
|
|
282
|
+
### Slots
|
|
283
|
+
|
|
284
|
+
- `header` — above the scroll region
|
|
285
|
+
- `actions` / `controls` / `footer` — scoped `{ item }`, forwarded to `FeedItemBase` (`#footer` is shown only while the item body is open — use for reactions / comments)
|
|
286
|
+
- `empty` / `loading` / `loading-more` — replace defaults
|
|
287
|
+
|
|
288
|
+
### Events
|
|
289
|
+
|
|
290
|
+
- `reach-bottom` — crossed into the near-end scroll zone (host loads next page)
|
|
291
|
+
- `fullscreen` / `start-skill` / `skill-click` / `control-click` / `expand` / `collapse` — item payloads
|
|
292
|
+
- `action` — `(item, event)` from a `type: 'card'` row (`verb`, `inputs`, …). Host performs the side effect.
|
|
293
|
+
- `update:item-expanded` — `(item, expanded)` when a row expand state changes
|
|
294
|
+
|
|
295
|
+
## IDW Cards
|
|
296
|
+
|
|
297
|
+
Schema-driven body documents for feed items, canvas, and other hosts. This is **not** Adaptive Cards. `FeedItemBase` / `FeedList` stay host chrome (envelope). `CardRenderer` renders **body + actions** only.
|
|
298
|
+
|
|
299
|
+
The `idw.card` schema and authoring skill live in [`@onereach/idw-contracts`](../contracts). Agents that **author** card JSON (or `templateId` + data) should follow [`../contracts/skills/idw-card-authoring/SKILL.md`](../contracts/skills/idw-card-authoring/SKILL.md). Hosts that **render** cards use `CardRenderer` below. This package re-exports the schema so existing imports keep working.
|
|
300
|
+
|
|
301
|
+
Three layers:
|
|
302
|
+
|
|
303
|
+
| Layer | Role |
|
|
304
|
+
|---|---|
|
|
305
|
+
| Card schema (`idw.card` / `1.0`) | Allowed elements, actions, nesting, and URLs |
|
|
306
|
+
| Template | A reusable card document with `${path}` / `$when` bindings |
|
|
307
|
+
| Template data schema | Domain payload for that template (e.g. approval) |
|
|
308
|
+
|
|
309
|
+
The card JSON has no theme or raw colors. The host passes `hostConfig.theme` (`dark` default). Surfaces always use paired light + `dark:` token classes.
|
|
310
|
+
|
|
311
|
+
```vue
|
|
312
|
+
<script setup lang="ts">
|
|
313
|
+
import {
|
|
314
|
+
CardRenderer,
|
|
315
|
+
cardFromMarkdown,
|
|
316
|
+
type IdwCardActionEvent,
|
|
317
|
+
} from '@onereach/idw-ui-components';
|
|
318
|
+
|
|
319
|
+
function onAction(event: IdwCardActionEvent) {
|
|
320
|
+
// host owns approve / reject / start-skill / …
|
|
321
|
+
}
|
|
322
|
+
</script>
|
|
323
|
+
|
|
324
|
+
<template>
|
|
325
|
+
<CardRenderer
|
|
326
|
+
:source="{
|
|
327
|
+
templateId: 'approval',
|
|
328
|
+
data: {
|
|
329
|
+
title: 'Time off',
|
|
330
|
+
summary: 'Approve vacation next Friday.',
|
|
331
|
+
requester: 'Ada Lovelace',
|
|
332
|
+
dueAt: 'Friday',
|
|
333
|
+
},
|
|
334
|
+
}"
|
|
335
|
+
@action="onAction"
|
|
336
|
+
/>
|
|
337
|
+
|
|
338
|
+
<CardRenderer :source="{ card: cardFromMarkdown('**Hello**') }" />
|
|
339
|
+
</template>
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### v1 elements
|
|
343
|
+
|
|
344
|
+
Layout / content: `Text` (Markdown), `Image`, `ImageSet`, `FactSet`, `Container`, `ColumnSet` (2–3 columns), `Table`, `Media`, `Html`, `File`, `Skill`, `ActionSet`, `Badge`, `Icon`, `Progress`.
|
|
345
|
+
|
|
346
|
+
Inputs (inspired by Adaptive Cards `Input.*`, plus IDW widgets). Every input has `name` (collected on action), plus optional `label`, `hint`, `required`, `errorMessage`, `disabled`:
|
|
347
|
+
|
|
348
|
+
| Type | Renders as | Notes |
|
|
349
|
+
|---|---|---|
|
|
350
|
+
| `Input.Text` | `OrInputV3` / `OrTextareaV3` | `multiline`, `style`: text/email/url/tel/password |
|
|
351
|
+
| `Input.Number` | `OrInputV3` | `min` / `max` / `step` |
|
|
352
|
+
| `Input.Toggle` | `OrSwitchV3` | boolean |
|
|
353
|
+
| `Input.Checkbox` | `OrCheckboxV3` | boolean |
|
|
354
|
+
| `Input.ChoiceSet` | select / radio / checkbox group | `style`: compact / expanded / filtered; `multi` |
|
|
355
|
+
| `Input.Date` | `OrDatePickerV3` | ISO date string |
|
|
356
|
+
| `Input.Time` | `OrTimePickerV3` | `HH:mm` |
|
|
357
|
+
| `Input.DateTime` | `OrDateTimePickerV3` | ISO datetime |
|
|
358
|
+
| `Input.Slider` | `OrSliderV3` | number |
|
|
359
|
+
| `Input.Range` | `OrRangeSliderV3` | `[from, to]` |
|
|
360
|
+
| `Input.Rating` | `OrRatingV3` | number |
|
|
361
|
+
| `Input.Location` | address (+ optional lat/lng) | `{ address, lat?, lng? }` |
|
|
362
|
+
|
|
363
|
+
Spacing: `none | xs | sm | md | lg | xl`. Text style: `caption | body | headline`. Tone: `default | emphasis | success | warning | attention`.
|
|
364
|
+
|
|
365
|
+
This is **not** Adaptive Cards JSON. We borrowed the input/container/action model (including ChoiceSet, Table, Media, ImageSet, ShowCard, ToggleVisibility) and mapped it onto or-components.
|
|
366
|
+
|
|
367
|
+
Not in v1 (AC/Copilot extras we skipped on purpose): Refresh, Authentication, Carousel, Charts, `Data.Query` remote choices, `selectAction`, `RichTextBlock` runs, and `Action.Execute`. `Input.Location` has no or-component — it is address text plus optional lat/lng, not a map picker.
|
|
368
|
+
|
|
369
|
+
### Closed actions
|
|
370
|
+
|
|
371
|
+
`open-url`, `approve`, `reject`, `submit`, `start-skill`, `mention`, `open-conversation`, `toggle-visibility` (`targetIds`), `show-card` (`card`).
|
|
372
|
+
|
|
373
|
+
`CardRenderer` emits `action` `{ verb, title, data?, url?, skillId?, targetIds?, card?, inputs? }` and forwards `skill-click`. `approve` / `reject` / `submit` validate required inputs first and attach the current `inputs` map. The host performs the side effect.
|
|
374
|
+
|
|
375
|
+
Helpers: `cardFromMarkdown`, `cardFromHtml`, `cardFromFile`, `cardFromSkill`, `validateIdwCard`, `bindIdwCard`, `resolveCardRendererSource`.
|
|
376
|
+
|
|
377
|
+
Html/file embeds reuse `FEED_EMBED_SANDBOX` and it is not configurable from the card.
|