@monimesl/dot-cli 0.1.0-alpha.9 → 1.0.0-beta.1

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 (143) hide show
  1. package/README.md +72 -59
  2. package/dist/cli.js +539 -341
  3. package/dist/cli.js.map +1 -1
  4. package/dist/{server-BfPAnsSf.js → server-DMnWDdJ6.js} +570 -478
  5. package/dist/server-DMnWDdJ6.js.map +1 -0
  6. package/dist/templates/showcase/dot.ts +53 -16
  7. package/dist/templates/showcase/pages/basics/bars/controller.ts +47 -0
  8. package/dist/templates/showcase/pages/basics/bars/state.ts +7 -0
  9. package/dist/templates/showcase/pages/basics/bars/view.dml +36 -0
  10. package/dist/templates/showcase/pages/{text → basics/bindings}/controller.ts +5 -0
  11. package/dist/templates/showcase/pages/basics/bindings/state.ts +14 -0
  12. package/dist/templates/showcase/pages/basics/bindings/view.dml +41 -0
  13. package/dist/templates/showcase/pages/basics/colors/controller.ts +112 -0
  14. package/dist/templates/showcase/pages/basics/colors/palette.ts +52 -0
  15. package/dist/templates/showcase/pages/basics/colors/state.ts +17 -0
  16. package/dist/templates/showcase/pages/basics/colors/view.dml +142 -0
  17. package/dist/templates/showcase/pages/basics/concert/controller.ts +16 -0
  18. package/dist/templates/showcase/pages/basics/concert/state.ts +7 -0
  19. package/dist/templates/showcase/pages/basics/concert/view.dml +20 -0
  20. package/dist/templates/showcase/pages/basics/control-flow/controller.ts +18 -0
  21. package/dist/templates/showcase/pages/basics/control-flow/state.ts +16 -0
  22. package/dist/templates/showcase/pages/basics/control-flow/view.dml +55 -0
  23. package/dist/templates/showcase/pages/basics/events/controller.ts +43 -0
  24. package/dist/templates/showcase/pages/basics/events/state.ts +11 -0
  25. package/dist/templates/showcase/pages/basics/events/view.dml +51 -0
  26. package/dist/templates/showcase/pages/basics/hooks/controller.ts +43 -0
  27. package/dist/templates/showcase/pages/basics/hooks/state.ts +10 -0
  28. package/dist/templates/showcase/pages/basics/hooks/view.dml +37 -0
  29. package/dist/templates/showcase/pages/basics/navigation/controller.ts +41 -0
  30. package/dist/templates/showcase/pages/basics/navigation/state.ts +11 -0
  31. package/dist/templates/showcase/pages/basics/navigation/view.dml +48 -0
  32. package/dist/templates/showcase/pages/basics/pick-genre/controller.ts +18 -0
  33. package/dist/templates/showcase/pages/basics/pick-genre/state.ts +3 -0
  34. package/dist/templates/showcase/pages/basics/pick-genre/view.dml +10 -0
  35. package/dist/templates/showcase/pages/basics/share/concerts.ts +31 -0
  36. package/dist/templates/showcase/pages/basics/share/controller.ts +12 -0
  37. package/dist/templates/showcase/pages/basics/share/state.ts +5 -0
  38. package/dist/templates/showcase/pages/basics/share/view.dml +21 -0
  39. package/dist/templates/showcase/pages/{state → basics/state}/controller.ts +1 -0
  40. package/dist/templates/showcase/pages/basics/state/view.dml +46 -0
  41. package/dist/templates/showcase/pages/{carousel → components/carousel}/controller.ts +2 -1
  42. package/dist/templates/showcase/pages/{carousel → components/carousel}/state.ts +5 -5
  43. package/dist/templates/showcase/pages/{carousel → components/carousel}/view.dml +7 -5
  44. package/dist/templates/showcase/pages/{feedback → components/feedback}/controller.ts +13 -2
  45. package/dist/templates/showcase/pages/components/feedback/state.ts +41 -0
  46. package/dist/templates/showcase/pages/{feedback → components/feedback}/view.dml +38 -9
  47. package/dist/templates/showcase/pages/{forms → components/forms}/controller.ts +23 -19
  48. package/dist/templates/showcase/pages/{forms → components/forms}/state.ts +6 -3
  49. package/dist/templates/showcase/pages/components/forms/view.dml +97 -0
  50. package/dist/templates/showcase/pages/components/icons/controller.ts +15 -0
  51. package/dist/templates/showcase/pages/components/icons/state.ts +75 -0
  52. package/dist/templates/showcase/pages/components/icons/view.dml +36 -0
  53. package/dist/templates/showcase/pages/{images → components/images}/controller.ts +4 -1
  54. package/dist/templates/showcase/pages/components/images/view.dml +83 -0
  55. package/dist/templates/showcase/pages/{layout → components/layout}/controller.ts +3 -2
  56. package/dist/templates/showcase/pages/components/layout/view.dml +143 -0
  57. package/dist/templates/showcase/pages/components/lists/controller.ts +18 -0
  58. package/dist/templates/showcase/pages/{lists → components/lists}/state.ts +43 -30
  59. package/dist/templates/showcase/pages/components/lists/view.dml +88 -0
  60. package/dist/templates/showcase/pages/{payments → components/money}/controller.ts +7 -8
  61. package/dist/templates/showcase/pages/components/money/view.dml +54 -0
  62. package/dist/templates/showcase/pages/components/reading/controller.ts +6 -0
  63. package/dist/templates/showcase/pages/components/reading/state.ts +23 -0
  64. package/dist/templates/showcase/pages/components/reading/view.dml +42 -0
  65. package/dist/templates/showcase/pages/{lists → components/sheets}/controller.ts +10 -11
  66. package/dist/templates/showcase/pages/components/sheets/state.ts +26 -0
  67. package/dist/templates/showcase/pages/components/sheets/view.dml +38 -0
  68. package/dist/templates/showcase/pages/components/styles/controller.ts +6 -0
  69. package/dist/templates/showcase/pages/components/styles/state.ts +3 -0
  70. package/dist/templates/showcase/pages/components/styles/view.dml +101 -0
  71. package/dist/templates/showcase/pages/components/tabs/controller.ts +41 -0
  72. package/dist/templates/showcase/pages/{filters → components/tabs}/state.ts +32 -23
  73. package/dist/templates/showcase/pages/components/tabs/view.dml +57 -0
  74. package/dist/templates/showcase/pages/components/text/controller.ts +10 -0
  75. package/dist/templates/showcase/pages/components/text/state.ts +3 -0
  76. package/dist/templates/showcase/pages/components/text/view.dml +95 -0
  77. package/dist/templates/showcase/pages/dash/account/controller.ts +32 -0
  78. package/dist/templates/showcase/pages/dash/account/state.ts +9 -0
  79. package/dist/templates/showcase/pages/dash/account/view.dml +33 -0
  80. package/dist/templates/showcase/pages/{cache → dash/cache}/controller.ts +9 -4
  81. package/dist/templates/showcase/pages/dash/cache/view.dml +48 -0
  82. package/dist/templates/showcase/pages/dash/calls/controller.ts +67 -0
  83. package/dist/templates/showcase/pages/dash/calls/state.ts +9 -0
  84. package/dist/templates/showcase/pages/dash/calls/view.dml +69 -0
  85. package/dist/templates/showcase/pages/dash/contacts/controller.ts +30 -0
  86. package/dist/templates/showcase/pages/dash/contacts/state.ts +6 -0
  87. package/dist/templates/showcase/pages/dash/contacts/view.dml +33 -0
  88. package/dist/templates/showcase/pages/dash/crypto/controller.ts +38 -0
  89. package/dist/templates/showcase/pages/dash/crypto/state.ts +10 -0
  90. package/dist/templates/showcase/pages/dash/crypto/view.dml +48 -0
  91. package/dist/templates/showcase/pages/{files → dash/files}/controller.ts +7 -2
  92. package/dist/templates/showcase/pages/{files → dash/files}/state.ts +4 -0
  93. package/dist/templates/showcase/pages/dash/files/view.dml +78 -0
  94. package/dist/templates/showcase/pages/dash/media/controller.ts +65 -0
  95. package/dist/templates/showcase/pages/dash/media/state.ts +12 -0
  96. package/dist/templates/showcase/pages/dash/media/view.dml +53 -0
  97. package/dist/templates/showcase/pages/{network → dash/network}/controller.ts +84 -20
  98. package/dist/templates/showcase/pages/{network → dash/network}/state.ts +14 -1
  99. package/dist/templates/showcase/pages/dash/network/view.dml +108 -0
  100. package/dist/templates/showcase/pages/dash/payments/cases.ts +445 -0
  101. package/dist/templates/showcase/pages/dash/payments/controller.ts +149 -0
  102. package/dist/templates/showcase/pages/dash/payments/state.ts +33 -0
  103. package/dist/templates/showcase/pages/dash/payments/view.dml +71 -0
  104. package/dist/templates/showcase/pages/{secrets → dash/secrets}/controller.ts +2 -1
  105. package/dist/templates/showcase/pages/dash/secrets/view.dml +26 -0
  106. package/dist/templates/showcase/pages/dash/system/controller.ts +89 -0
  107. package/dist/templates/showcase/pages/dash/system/state.ts +13 -0
  108. package/dist/templates/showcase/pages/dash/system/view.dml +96 -0
  109. package/dist/templates/showcase/pages/dash/ui/controller.ts +70 -0
  110. package/dist/templates/showcase/pages/dash/ui/state.ts +8 -0
  111. package/dist/templates/showcase/pages/dash/ui/view.dml +31 -0
  112. package/dist/templates/showcase/pages/index/controller.ts +1 -1
  113. package/dist/templates/showcase/pages/index/state.ts +175 -60
  114. package/dist/templates/showcase/pages/index/view.dml +6 -3
  115. package/package.json +6 -6
  116. package/dist/server-BfPAnsSf.js.map +0 -1
  117. package/dist/templates/showcase/pages/cache/view.dml +0 -36
  118. package/dist/templates/showcase/pages/device/controller.ts +0 -80
  119. package/dist/templates/showcase/pages/device/state.ts +0 -7
  120. package/dist/templates/showcase/pages/device/view.dml +0 -49
  121. package/dist/templates/showcase/pages/feedback/state.ts +0 -8
  122. package/dist/templates/showcase/pages/files/view.dml +0 -50
  123. package/dist/templates/showcase/pages/filters/controller.ts +0 -27
  124. package/dist/templates/showcase/pages/filters/view.dml +0 -44
  125. package/dist/templates/showcase/pages/forms/view.dml +0 -49
  126. package/dist/templates/showcase/pages/images/view.dml +0 -53
  127. package/dist/templates/showcase/pages/layout/view.dml +0 -103
  128. package/dist/templates/showcase/pages/lists/view.dml +0 -59
  129. package/dist/templates/showcase/pages/navigation/controller.ts +0 -65
  130. package/dist/templates/showcase/pages/navigation/state.ts +0 -17
  131. package/dist/templates/showcase/pages/navigation/view.dml +0 -34
  132. package/dist/templates/showcase/pages/network/view.dml +0 -67
  133. package/dist/templates/showcase/pages/payments/view.dml +0 -45
  134. package/dist/templates/showcase/pages/secrets/view.dml +0 -24
  135. package/dist/templates/showcase/pages/state/view.dml +0 -33
  136. package/dist/templates/showcase/pages/text/state.ts +0 -8
  137. package/dist/templates/showcase/pages/text/view.dml +0 -58
  138. /package/dist/templates/showcase/pages/{state → basics/state}/state.ts +0 -0
  139. /package/dist/templates/showcase/pages/{images → components/images}/state.ts +0 -0
  140. /package/dist/templates/showcase/pages/{layout → components/layout}/state.ts +0 -0
  141. /package/dist/templates/showcase/pages/{payments → components/money}/state.ts +0 -0
  142. /package/dist/templates/showcase/pages/{cache → dash/cache}/state.ts +0 -0
  143. /package/dist/templates/showcase/pages/{secrets → dash/secrets}/state.ts +0 -0
@@ -0,0 +1,143 @@
1
+ <View>
2
+ <Text variant="title">Layout</Text>
3
+ <Text>Views hold other components and lay them out. Every page starts with one.</Text>
4
+
5
+ <View gap="small">
6
+ <Text variant="subtitle">View</Text>
7
+ <Text variant="caption" tone="muted">A View puts its items in a column or a row. variant="card" gives it a card's look. Change the one below.</Text>
8
+ <View variant="card" direction="{{ direction }}" justify="{{ justify }}" align="{{ align }}" gap="{{ gap }}" wrap="{{ wrap }}">
9
+ <Button variant="secondary">Palm-wine</Button>
10
+ <Button variant="secondary">Gumbe</Button>
11
+ <Text variant="title">Afropop</Text>
12
+ <Button variant="secondary">Bubu</Button>
13
+ <Text variant="caption" tone="muted">Milo jazz</Text>
14
+ </View>
15
+ <View gap="small">
16
+ <View direction="row" align="center">
17
+ <Text>direction="{{ direction }}"</Text>
18
+ <View grow />
19
+ <Button variant="secondary" onClick="nextDirection">Change</Button>
20
+ </View>
21
+ <View direction="row" align="center">
22
+ <Text>justify="{{ justify }}"</Text>
23
+ <View grow />
24
+ <Button variant="secondary" onClick="nextJustify">Change</Button>
25
+ </View>
26
+ <View direction="row" align="center">
27
+ <Text>align="{{ align }}"</Text>
28
+ <View grow />
29
+ <Button variant="secondary" onClick="nextAlign">Change</Button>
30
+ </View>
31
+ <View direction="row" align="center">
32
+ <Text>gap="{{ gap }}"</Text>
33
+ <View grow />
34
+ <Button variant="secondary" onClick="nextGap">Change</Button>
35
+ </View>
36
+ <View direction="row" align="center">
37
+ <Text>wrap="{{ wrap }}"</Text>
38
+ <View grow />
39
+ <Button variant="secondary" onClick="toggleWrap">Change</Button>
40
+ </View>
41
+ </View>
42
+ </View>
43
+
44
+ <View gap="small">
45
+ <Text variant="subtitle">grow and onTap</Text>
46
+ <Text variant="caption" tone="muted">grow fills the space left over: the song grows, the year does not. A View can be tapped: tap the song.</Text>
47
+ <View direction="row" gap="small">
48
+ <View variant="card" grow onTap="playSong">
49
+ <Text>{{ playing ? 'Playing Exodus, by Drizilik' : 'Exodus, by Drizilik' }}</Text>
50
+ </View>
51
+ <View variant="card">
52
+ <Text>2021</Text>
53
+ </View>
54
+ </View>
55
+ </View>
56
+
57
+ <View gap="small">
58
+ <Text variant="subtitle">padding</Text>
59
+ <Text variant="caption" tone="muted">The space inside the edges, on every side or on one side. Most components take it.</Text>
60
+ <View direction="row" gap="small">
61
+ <View variant="card" padding="small">
62
+ <Text>small</Text>
63
+ </View>
64
+ <View variant="card" padding="large">
65
+ <Text>large</Text>
66
+ </View>
67
+ <View variant="card" padding="small" paddingStart="large">
68
+ <Text>start</Text>
69
+ </View>
70
+ </View>
71
+ </View>
72
+
73
+ <View gap="small">
74
+ <Text variant="subtitle">Stack</Text>
75
+ <Text variant="caption" tone="muted">A Stack lays its children on top of each other, such as words over a picture.</Text>
76
+ <Stack radius="large" aspect="16:9">
77
+ <View background="gold" />
78
+ <View justify="end" padding="large">
79
+ <Text variant="subtitle" tone="ink">Bo market day</Text>
80
+ <Text tone="ink">Every Saturday, from 7 am</Text>
81
+ </View>
82
+ <View align="end" padding="medium">
83
+ <View background="primary" radius="full" paddingStart="small" paddingEnd="small">
84
+ <Text variant="caption" tone="onPrimary" weight="bold">New</Text>
85
+ </View>
86
+ </View>
87
+ </Stack>
88
+ </View>
89
+
90
+ <View gap="small">
91
+ <Text variant="subtitle">Scroll</Text>
92
+ <Text variant="caption" tone="muted">A Scroll moves a row sideways. It stops at the start of each release. The buttons scroll it too.</Text>
93
+ <Scroll gap="medium" snap="start" index="{{ first }}" onChange="showFirst">
94
+ <For each="{{ releases }}" item="release" key="id">
95
+ <View gap="small">
96
+ <If condition="{{ release.cover }}">
97
+ <Image src="{{ release.cover }}" alt="{{ release.title }}" width="128" height="128" />
98
+ </If>
99
+ <Else>
100
+ <Skeleton shape="box" height="128" />
101
+ </Else>
102
+ <Text weight="medium" maxLines="2">{{ release.title }}</Text>
103
+ <Text variant="caption" tone="muted">{{ release.year }}</Text>
104
+ </View>
105
+ </For>
106
+ </Scroll>
107
+ <Text tone="muted">First on the shelf: {{ releases[first].title }}</Text>
108
+ <View direction="row" gap="small">
109
+ <Button variant="secondary" onClick="shelfStart" disabled="{{ first === 0 }}">To the start</Button>
110
+ <Button variant="secondary" onClick="shelfEnd" disabled="{{ first === releases.length - 1 }}">To the end</Button>
111
+ </View>
112
+ </View>
113
+
114
+ <View gap="small">
115
+ <Text variant="subtitle">Grid</Text>
116
+ <Text variant="caption" tone="muted">A Grid keeps its columns the same width. A GridItem shows an icon or a picture, with a label.</Text>
117
+ <View variant="card" gap="medium">
118
+ <Grid columns="4" gap="small">
119
+ <GridItem icon="microphone" label="Artists" data-name="Artists" onTap="openSection" />
120
+ <GridItem icon="music" label="Albums" data-name="Albums" onTap="openSection" />
121
+ <GridItem icon="playlist" label="Playlists" data-name="Playlists" onTap="openSection" />
122
+ <GridItem icon="star" label="Charts" badge="New" data-name="Charts" onTap="openSection" />
123
+ <GridItem icon="calendar" label="Shows" data-name="Shows" onTap="openSection" />
124
+ <GridItem icon="ticket" label="Tickets" data-name="Tickets" onTap="openSection" />
125
+ <GridItem icon="headphones" label="Library" data-name="Library" onTap="openSection" />
126
+ <GridItem image="statics/logo.png" label="Salone" data-name="Salone" onTap="openSection" />
127
+ </Grid>
128
+ <If condition="{{ section }}">
129
+ <Text tone="muted">You tapped {{ section }}</Text>
130
+ </If>
131
+ </View>
132
+ </View>
133
+
134
+ <View gap="small">
135
+ <Text variant="subtitle">Divider</Text>
136
+ <Text variant="caption" tone="muted">A line between parts.</Text>
137
+ <View variant="card">
138
+ <Text>Side A</Text>
139
+ <Divider />
140
+ <Text>Side B</Text>
141
+ </View>
142
+ </View>
143
+ </View>
@@ -0,0 +1,18 @@
1
+ import state, { CHART } from './state';
2
+
3
+ // Rows to add each time the list's end comes into view.
4
+ const MORE = 5;
5
+
6
+ export default definePage({
7
+ initialState: state,
8
+ configs: { navigationBar: { title: 'Lists' } },
9
+ mutations: {
10
+ choose: (state, event: DataEvent<{ id: string }>) => {
11
+ const artist = state.artists.find((candidate) => candidate.id === event.data.id);
12
+ return { chosen: artist?.name ?? '' };
13
+ },
14
+ showMore: (state) => ({ chart: CHART.slice(0, state.chart.length + MORE) }),
15
+ saveSome: () => ({ saved: ['Exodus, by Drizilik', 'Control, by ApreeL'] }),
16
+ clearSaved: () => ({ saved: [] }),
17
+ },
18
+ });
@@ -3,7 +3,6 @@ export interface Artist {
3
3
  name: string;
4
4
  song: string;
5
5
  genre: string;
6
- icon: string;
7
6
  }
8
7
 
9
8
  export interface Release {
@@ -15,6 +14,42 @@ export interface Release {
15
14
  tone: string;
16
15
  }
17
16
 
17
+ export interface ChartSong {
18
+ id: number;
19
+ title: string;
20
+ plays: string;
21
+ }
22
+
23
+ const TITLES = [
24
+ 'Lemonade',
25
+ 'Control',
26
+ 'Love Na Scam',
27
+ 'Hannah',
28
+ 'Nack',
29
+ 'Exodus',
30
+ 'Ashobi',
31
+ 'Send Money',
32
+ 'Blunt',
33
+ "O'way",
34
+ 'Shadow',
35
+ 'Leader',
36
+ 'Kenyatta',
37
+ 'Shock',
38
+ 'Leh Wi Make Salone',
39
+ 'Borbor Bele',
40
+ 'Let Me Love You',
41
+ 'Cry Africa',
42
+ 'Corruption',
43
+ 'Ghetto Struggle',
44
+ ];
45
+
46
+ // This week's chart. The list shows the first few, and more as you scroll.
47
+ export const CHART: ChartSong[] = TITLES.map((title, index) => ({
48
+ id: index + 1,
49
+ title,
50
+ plays: `${(20 - index) * 1000} plays`,
51
+ }));
52
+
18
53
  export default {
19
54
  artists: [
20
55
  {
@@ -22,32 +57,28 @@ export default {
22
57
  name: 'Drizilik',
23
58
  song: 'Lemonade, with The Therapist',
24
59
  genre: 'Kriofusion',
25
- icon: 'microphone',
26
60
  },
27
- { id: 'boii', name: 'Boii', song: 'Love Na Scam', genre: 'Afrobeats', icon: 'microphone' },
28
- { id: 'apreel', name: 'ApreeL', song: 'Control', genre: 'Afropop', icon: 'microphone' },
29
- { id: 'donii-major', name: 'Donii Major', song: 'Hannah', genre: 'R&B', icon: 'microphone' },
61
+ { id: 'boii', name: 'Boii', song: 'Love Na Scam', genre: 'Afrobeats' },
62
+ { id: 'apreel', name: 'ApreeL', song: 'Control', genre: 'Afropop' },
63
+ { id: 'donii-major', name: 'Donii Major', song: 'Hannah', genre: 'R&B' },
30
64
  {
31
65
  id: 'star-zee',
32
66
  name: 'Star Zee',
33
67
  song: 'Leader, with Stonebwoy',
34
68
  genre: 'Hip hop',
35
- icon: 'microphone',
36
69
  },
37
70
  {
38
71
  id: 'kao-denero',
39
72
  name: 'Kao Denero',
40
73
  song: 'Kenyatta',
41
74
  genre: 'Hip hop',
42
- icon: 'microphone',
43
75
  },
44
- { id: 'laj', name: 'LAJ', song: 'Shock, with Cassidy', genre: 'Hip hop', icon: 'microphone' },
76
+ { id: 'laj', name: 'LAJ', song: 'Shock, with Cassidy', genre: 'Hip hop' },
45
77
  {
46
78
  id: 'k-man',
47
79
  name: 'K-Man',
48
80
  song: 'Leh Wi Make Salone',
49
81
  genre: 'Hip hop',
50
- icon: 'microphone',
51
82
  },
52
83
  ] as Artist[],
53
84
  releases: [
@@ -93,25 +124,7 @@ export default {
93
124
  },
94
125
  ] as Release[],
95
126
  chosen: '',
96
- // The record whose actions the sheet shows.
97
- selected: null as Release | null,
98
- toast: '',
99
- icons: [
100
- 'music',
101
- 'playlist',
102
- 'microphone',
103
- 'headphones',
104
- 'ticket',
105
- 'video',
106
- 'globe',
107
- 'link',
108
- 'external-link',
109
- 'heart',
110
- 'star',
111
- 'share',
112
- 'download',
113
- 'calendar',
114
- 'location',
115
- 'search',
116
- ],
127
+ chart: CHART.slice(0, 8),
128
+ chartSize: CHART.length,
129
+ saved: [] as string[],
117
130
  };
@@ -0,0 +1,88 @@
1
+ <View>
2
+ <Text variant="title">Lists</Text>
3
+ <Text>A List shows rows in a card. A ListItem can show an icon or a picture, a subtitle, and a value or a badge at its end. A row you can tap shows an arrow.</Text>
4
+
5
+ <View gap="small">
6
+ <Text variant="subtitle">List and ListItem</Text>
7
+ <Text variant="caption" tone="muted">Artists in a small list. Tap one: its data-id tells the page which one.</Text>
8
+ <List>
9
+ <For each="{{ artists }}" item="artist" key="id">
10
+ <ListItem icon="microphone" title="{{ artist.name }}" subtitle="{{ artist.song }}" value="{{ artist.genre }}" data-id="{{ artist.id }}" onTap="choose" />
11
+ </For>
12
+ </List>
13
+ <If condition="{{ chosen }}">
14
+ <Text>You chose {{ chosen }}</Text>
15
+ </If>
16
+ </View>
17
+
18
+ <View gap="small">
19
+ <Text variant="subtitle">size="md", with a picture and a badge</Text>
20
+ <Text variant="caption" tone="muted">Medium lists have more room. A ListItem's children show at its end, in place of value.</Text>
21
+ <List size="md">
22
+ <For each="{{ releases }}" item="release" key="id">
23
+ <ListItem image="statics/logo.png" title="{{ release.title }}" subtitle="{{ release.artist }} · {{ release.year }}">
24
+ <Badge tone="{{ release.tone }}">{{ release.note }}</Badge>
25
+ </ListItem>
26
+ </For>
27
+ </List>
28
+ </View>
29
+
30
+ <View gap="small">
31
+ <Text variant="subtitle">onEndReached</Text>
32
+ <Text variant="caption" tone="muted">Comes when the last row scrolls into view, so the page can add more. {{ chart.length }} of {{ chartSize }} songs so far.</Text>
33
+ <List onEndReached="showMore">
34
+ <For each="{{ chart }}" item="song" key="id">
35
+ <ListItem title="{{ song.id }}. {{ song.title }}" value="{{ song.plays }}" />
36
+ </For>
37
+ </List>
38
+ </View>
39
+
40
+ <View gap="small">
41
+ <Text variant="subtitle">DetailRow</Text>
42
+ <Text variant="caption" tone="muted">A label with its value, such as on a receipt. tone and weight change the value.</Text>
43
+ <View variant="card" gap="none">
44
+ <DetailRow label="Show" value="Salone Sounds Live" />
45
+ <DetailRow label="Seats" value="2, near the stage" tone="muted" />
46
+ <DetailRow label="Doors open" value="18:00" tone="info" />
47
+ <DetailRow label="Status" value="Paid" tone="success" />
48
+ <DetailRow label="Refunds" value="Not after Friday" tone="warning" />
49
+ <DetailRow label="Total" value="SLE 800" weight="bold" />
50
+ </View>
51
+ </View>
52
+
53
+ <View gap="small">
54
+ <Text variant="subtitle">Disclosure</Text>
55
+ <Text variant="caption" tone="muted">A row that opens to show more, such as an answer. The person opens and closes it, and open sets how it starts.</Text>
56
+ <View variant="card" gap="none">
57
+ <Disclosure title="Can I get a refund?" subtitle="Tickets and refunds" open>
58
+ <Text>Yes, until the Friday before the show. After that, you can give your ticket to someone else.</Text>
59
+ </Disclosure>
60
+ <Divider />
61
+ <Disclosure title="When do doors open?">
62
+ <Text>At 6 pm. The music starts at 7.</Text>
63
+ </Disclosure>
64
+ <Divider />
65
+ <Disclosure title="Is there parking?">
66
+ <Text>Yes, at the Lumley junction car park, a short walk away.</Text>
67
+ </Disclosure>
68
+ </View>
69
+ </View>
70
+
71
+ <View gap="small">
72
+ <Text variant="subtitle">EmptyState</Text>
73
+ <Text variant="caption" tone="muted">Shows when a list has nothing in it, with a way forward.</Text>
74
+ <View variant="card">
75
+ <If condition="{{ saved.length > 0 }}">
76
+ <For each="{{ saved }}" item="title" key="*this">
77
+ <Text>{{ title }}</Text>
78
+ </For>
79
+ <Button variant="secondary" onClick="clearSaved">Clear</Button>
80
+ </If>
81
+ <Else>
82
+ <EmptyState icon="heart" title="No saved songs" text="Save a song to find it here later.">
83
+ <Button variant="secondary" onClick="saveSome">Save two songs</Button>
84
+ </EmptyState>
85
+ </Else>
86
+ </View>
87
+ </View>
88
+ </View>
@@ -1,7 +1,5 @@
1
1
  import state from './state';
2
2
 
3
- type Typed = DotEvent<{ value: string }>;
4
-
5
3
  // The code this page accepts; a real dot checks it with its server.
6
4
  const RIGHT_CODE = '123456';
7
5
 
@@ -10,8 +8,9 @@ const MAX_PLEDGE = 1000;
10
8
 
11
9
  export default definePage({
12
10
  initialState: state,
11
+ configs: { navigationBar: { title: 'Money and codes' } },
13
12
  mutations: {
14
- setAmount: (_state, event: DotEvent<{ value: number | null }>) => {
13
+ setAmount: (_state, event: ValueEvent<number | null>) => {
15
14
  const amount = event.detail.value;
16
15
  if (!amount) {
17
16
  return { amount, amountText: '', request: '' };
@@ -22,20 +21,20 @@ export default definePage({
22
21
  request: `https://pay.example.com/tip?amount=${amount}&currency=SLE&in=cents`,
23
22
  };
24
23
  },
25
- setCode: (_state, event: Typed) => ({ code: event.detail.value, codeError: '' }),
26
- checkCode: (_state, event: Typed) => {
24
+ setCode: (_state, event: ValueEvent) => ({ code: event.detail.value, codeError: '' }),
25
+ checkCode: (_state, event: ValueEvent) => {
27
26
  if (event.detail.value === RIGHT_CODE) {
28
27
  return { verified: true };
29
28
  }
30
29
  return { code: '', codeError: 'That code is wrong. Try again.' };
31
30
  },
32
31
  startAgain: () => ({ verified: false, code: '' }),
33
- setPin: (_state, event: Typed) => ({ pin: event.detail.value }),
32
+ setPin: (_state, event: ValueEvent) => ({ pin: event.detail.value }),
34
33
  clearPin: () => ({ pin: '' }),
35
- setLocked: (_state, event: DotEvent<{ checked: boolean }>) => ({
34
+ setLocked: (_state, event: CheckedEvent) => ({
36
35
  locked: event.detail.checked,
37
36
  }),
38
- setPledge: (_state, event: DotEvent<{ value: number | null }>) => {
37
+ setPledge: (_state, event: ValueEvent<number | null>) => {
39
38
  const pledge = event.detail.value;
40
39
  return {
41
40
  pledge,
@@ -0,0 +1,54 @@
1
+ <View>
2
+ <Text variant="title">Money and codes</Text>
3
+ <Text>Fields for amounts and codes, and QR codes to scan. Tip the band, pledge to its tour, and confirm your tickets.</Text>
4
+
5
+ <View gap="small">
6
+ <Text variant="subtitle">AmountInput</Text>
7
+ <Text variant="caption" tone="muted">Formats the amount as you type. It sends a number in cents, the minor unit, so 150 is SLE 1.50.</Text>
8
+ <AmountInput label="Tip for the band" placeholder="0.00" value="{{ amount }}" disabled="{{ locked }}" onChange="setAmount" hint="The QR code below asks for it" />
9
+ <Switch label="Lock the tip" checked="{{ locked }}" onChange="setLocked" />
10
+ </View>
11
+
12
+ <View gap="small">
13
+ <Text variant="subtitle">QRCode</Text>
14
+ <Text variant="caption" tone="muted">Shows text, such as a payment link, as a QR code. It's dark on light in every theme, so any camera can read it.</Text>
15
+ <View variant="card" align="center" gap="medium">
16
+ <If condition="{{ request }}">
17
+ <QRCode value="{{ request }}" size="180" label="A QR code to tip SLE {{ amountText }}" />
18
+ <Text tone="muted">Scan to tip the band SLE {{ amountText }}</Text>
19
+ </If>
20
+ <Else>
21
+ <EmptyState icon="qr-code" title="No tip yet" text="Type an amount above to make a QR code the crowd can scan." />
22
+ </Else>
23
+ </View>
24
+ </View>
25
+
26
+ <View gap="small">
27
+ <Text variant="subtitle">currency, unit and minorUnits</Text>
28
+ <Text variant="caption" tone="muted">In US dollars. unit="major" sends dollars, not cents, and minorUnits="0" leaves the cents off.</Text>
29
+ <AmountInput label="Pledge for the band's Mano River tour" currency="USD" unit="major" minorUnits="0" value="{{ pledge }}" error="{{ pledgeError }}" hint="Up to USD 1,000" onChange="setPledge" />
30
+ </View>
31
+
32
+ <View gap="small">
33
+ <Text variant="subtitle">CodeInput</Text>
34
+ <Text variant="caption" tone="muted">A one-time code, one box per digit. Type it, paste it, or let the phone fill it from an SMS. onComplete comes when the last box fills.</Text>
35
+ <If condition="{{ verified }}">
36
+ <Notice tone="success" title="Code accepted">Your two tickets are confirmed.</Notice>
37
+ <Button variant="secondary" onClick="startAgain">Start again</Button>
38
+ </If>
39
+ <Else>
40
+ <CodeInput label="The code we sent to 076 •••• 21" value="{{ code }}" onChange="setCode" onComplete="checkCode" error="{{ codeError }}" hint="Use 123456" />
41
+ </Else>
42
+ </View>
43
+
44
+ <View gap="small">
45
+ <Text variant="subtitle">A PIN</Text>
46
+ <Text variant="caption" tone="muted">length="4" and secure, which hides the digits. Here it locks once complete.</Text>
47
+ <CodeInput label="PIN" length="4" secure value="{{ pin }}" disabled="{{ pin.length === 4 }}" onChange="setPin" />
48
+ <View direction="row" align="center" gap="small">
49
+ <Text tone="muted">{{ pin.length }} of 4 digits</Text>
50
+ <View grow />
51
+ <Button variant="secondary" onClick="clearPin" disabled="{{ pin.length === 0 }}">Clear the PIN</Button>
52
+ </View>
53
+ </View>
54
+ </View>
@@ -0,0 +1,6 @@
1
+ import state from './state';
2
+
3
+ export default definePage({
4
+ initialState: state,
5
+ configs: { navigationBar: { title: 'Reading' } },
6
+ });
@@ -0,0 +1,23 @@
1
+ // As a news app would get an article's body from its server. The lines are joined here so the
2
+ // production build stays on one line.
3
+ const body = [
4
+ "## What's on sale",
5
+ '',
6
+ 'Stalls opened before dawn, and by eight the **rice** sellers had a queue. Prices are set each morning and shown at the gate:',
7
+ '',
8
+ '- Rice, a cup: SLE 5',
9
+ '- Palm oil, a pint: SLE 12',
10
+ '- Pepper, a heap: SLE 3',
11
+ '',
12
+ "> The roof keeps the rain off. That's half the battle in July.",
13
+ '',
14
+ "Read the [council's notice](https://example.com/lumley-market) for opening hours, or see _Getting there_ below.",
15
+ '',
16
+ '### Getting there',
17
+ '',
18
+ 'Poda-podas from Lumley junction stop at the gate. The car park opens next month.',
19
+ ].join('\n');
20
+
21
+ export default {
22
+ body,
23
+ };
@@ -0,0 +1,42 @@
1
+ <View>
2
+ <Text variant="title">Reading</Text>
3
+ <Text>Prose lays out long text, such as a news story, so it reads well. Quote sets someone's words apart. BulletList lists points. RichText draws Markdown from a server.</Text>
4
+ <Divider />
5
+
6
+ <Prose>
7
+ <Text variant="caption" tone="muted" weight="medium">FREETOWN · 11 OCTOBER</Text>
8
+ <Text variant="title">Lumley's new market opens to traders and a long queue</Text>
9
+ <Text variant="lead">More than two hundred traders moved into the covered market on Saturday, the first in the west of the city.</Text>
10
+ <Text variant="caption" tone="muted">By Mariama Kamara</Text>
11
+ <Text>The market took two years to build, on the old lorry park by the junction. Each trader has:</Text>
12
+ <BulletList>
13
+ <Bullet>
14
+ <Text>a stall with a lock</Text>
15
+ </Bullet>
16
+ <Bullet>
17
+ <Text>water at both ends of the hall</Text>
18
+ </Bullet>
19
+ <Bullet>
20
+ <Text>a place in the car park, from next month</Text>
21
+ </Bullet>
22
+ </BulletList>
23
+ <Quote cite="Fatmata Conteh, who sells cloth">
24
+ <Text>For twelve years I sold under an umbrella. Now I have a door that closes.</Text>
25
+ </Quote>
26
+ <Text>The council says it will open a second market in Kissy next year. <Text weight="bold">Stalls there are free</Text> for the first six months. To get one:</Text>
27
+ <BulletList ordered>
28
+ <Bullet>
29
+ <Text>Register at the council office in Lumley.</Text>
30
+ </Bullet>
31
+ <Bullet>
32
+ <Text>Bring a photo and your trader's card.</Text>
33
+ </Bullet>
34
+ <Bullet>
35
+ <Text>Wait for an SMS with your stall number.</Text>
36
+ </Bullet>
37
+ </BulletList>
38
+ <Divider />
39
+ <Text variant="caption" tone="muted">The rest of the story comes as Markdown from the newsroom's server, drawn by RichText.</Text>
40
+ </Prose>
41
+ <RichText markdown="{{ body }}" />
42
+ </View>
@@ -2,15 +2,17 @@ import state from './state';
2
2
 
3
3
  export default definePage({
4
4
  initialState: state,
5
+ configs: { navigationBar: { title: 'Sheets' } },
5
6
  mutations: {
6
- choose: (state, event: DotEvent<unknown, { id: string }>) => {
7
- const artist = state.artists.find((candidate) => candidate.id === event.data.id);
8
- return { chosen: artist?.name ?? '' };
9
- },
10
- openRelease: (state, event: DotEvent<unknown, { id: string }>) => ({
7
+ openRelease: (state, event: DataEvent<{ id: string }>) => ({
11
8
  selected: state.releases.find((release) => release.id === event.data.id) ?? null,
12
9
  }),
13
- closeSheet: () => ({ selected: null }),
10
+ // A sheet doesn't close itself: the page sets `open` back to false.
11
+ closeRelease: () => ({ selected: null }),
12
+ openRating: () => ({ rating: true }),
13
+ closeRating: () => ({ rating: false }),
14
+ setStars: (_state, event: ValueEvent<number>) => ({ stars: event.detail.value }),
15
+ saveRating: (state) => ({ rating: false, saved: state.stars, toast: 'Thanks for rating' }),
14
16
  clearToast: () => ({ toast: '' }),
15
17
  },
16
18
  actions: {
@@ -26,12 +28,9 @@ export default definePage({
26
28
  if (!state.selected) {
27
29
  return;
28
30
  }
29
- const { title, artist, year, note } = state.selected;
31
+ const { title, artist, year } = state.selected;
30
32
  this.setState({ selected: null });
31
- await this.dash.system.share({
32
- title,
33
- text: `${title}, by ${artist} (${year}): ${note.toLowerCase()}.`,
34
- });
33
+ await this.dash.system.share({ title, text: `${title}, by ${artist} (${year})` });
35
34
  },
36
35
  },
37
36
  });
@@ -0,0 +1,26 @@
1
+ export interface Release {
2
+ id: string;
3
+ title: string;
4
+ artist: string;
5
+ year: number;
6
+ }
7
+
8
+ export default {
9
+ releases: [
10
+ {
11
+ id: 'rise-and-shine',
12
+ title: 'Rise & Shine',
13
+ artist: "Sierra Leone's Refugee All Stars",
14
+ year: 2010,
15
+ },
16
+ { id: 'kormot-bi-en-me', title: 'Kormot Bi En Me', artist: 'Steady Bongo', year: 1996 },
17
+ { id: 'borbor-bele', title: 'Borbor Bele', artist: 'Emmerson', year: 2004 },
18
+ ] as Release[],
19
+ // The record whose actions the sheet shows.
20
+ selected: null as Release | null,
21
+ // The rating sheet, and the rating it last saved.
22
+ rating: false,
23
+ stars: 3,
24
+ saved: 0,
25
+ toast: '',
26
+ };
@@ -0,0 +1,38 @@
1
+ <View>
2
+ <Text variant="title">Sheets</Text>
3
+ <Text>A Sheet slides up over the page while open is true. Tapping outside it, or its close icon, raises onClose. The page closes it by setting open back to false.</Text>
4
+
5
+ <View gap="small">
6
+ <Text variant="subtitle">An action sheet</Text>
7
+ <Text variant="caption" tone="muted">Tap a record to see what you can do with it.</Text>
8
+ <List>
9
+ <For each="{{ releases }}" item="release" key="id">
10
+ <ListItem icon="music" title="{{ release.title }}" subtitle="{{ release.artist }} · {{ release.year }}" data-id="{{ release.id }}" onTap="openRelease" />
11
+ </For>
12
+ </List>
13
+ </View>
14
+
15
+ <View gap="small">
16
+ <Text variant="subtitle">A sheet with a form</Text>
17
+ <Text variant="caption" tone="muted">Any component can go in a sheet. This one has no close icon, and more room inside.</Text>
18
+ <View variant="card" direction="row" align="center" gap="small">
19
+ <View grow>
20
+ <Text>{{ saved ? 'You gave ' + saved + ' stars' : 'Not rated yet' }}</Text>
21
+ </View>
22
+ <Button variant="secondary" onClick="openRating">Rate the show</Button>
23
+ </View>
24
+ </View>
25
+
26
+ <Sheet open="{{ selected !== null }}" title="{{ selected.title }} · {{ selected.year }}" showCloseIcon onClose="closeRelease">
27
+ <Button variant="secondary" onClick="copyTitle">Copy the title</Button>
28
+ <Button variant="secondary" onClick="shareRelease">Share it</Button>
29
+ <Button onClick="closeRelease">Cancel</Button>
30
+ </Sheet>
31
+
32
+ <Sheet open="{{ rating }}" title="Rate Salone Sounds Live" padding="large" onClose="closeRating">
33
+ <Slider label="Stars" min="1" max="5" showValue value="{{ stars }}" onChange="setStars" />
34
+ <Button onClick="saveRating">Save</Button>
35
+ </Sheet>
36
+
37
+ <Toast message="{{ toast }}" tone="success" onHide="clearToast" />
38
+ </View>
@@ -0,0 +1,6 @@
1
+ import state from './state';
2
+
3
+ export default definePage({
4
+ initialState: state,
5
+ configs: { navigationBar: { title: 'Styles' } },
6
+ });