@globalbrain/sefirot 0.70.0 → 2.0.0-draft.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 (174) hide show
  1. package/CHANGELOG.md +2 -800
  2. package/README.md +1 -1
  3. package/lib/assets/styles/bootstrap.css +1 -2
  4. package/lib/assets/styles/variables.css +14 -47
  5. package/lib/components/SAvatar.vue +9 -18
  6. package/lib/components/SButton.vue +35 -48
  7. package/lib/components/SDialog.vue +16 -34
  8. package/lib/components/SDropdown.vue +36 -55
  9. package/lib/components/SDropdownItem.vue +27 -39
  10. package/lib/components/SDropdownItemText.vue +4 -9
  11. package/lib/components/SDropdownItemUser.vue +4 -12
  12. package/lib/components/SInputBase.vue +33 -45
  13. package/lib/components/SInputCheckbox.vue +19 -35
  14. package/lib/components/SInputDropdown.vue +109 -171
  15. package/lib/components/SInputDropdownItem.vue +26 -32
  16. package/lib/components/SInputDropdownItemText.vue +6 -11
  17. package/lib/components/SInputDropdownItemTextTag.vue +10 -17
  18. package/lib/components/SInputDropdownItemUser.vue +5 -13
  19. package/lib/components/SInputDropdownItemUserTag.vue +9 -16
  20. package/lib/components/SInputFile.vue +38 -53
  21. package/lib/components/SInputHMS.vue +91 -114
  22. package/lib/components/SInputNumber.vue +27 -106
  23. package/lib/components/SInputRadio.vue +23 -33
  24. package/lib/components/SInputRadios.vue +37 -47
  25. package/lib/components/SInputText.vue +59 -632
  26. package/lib/components/SInputTextarea.vue +54 -113
  27. package/lib/components/SInputYMD.vue +94 -105
  28. package/lib/components/SLink.vue +16 -52
  29. package/lib/components/SModal.vue +53 -90
  30. package/lib/components/SPortalModals.vue +37 -53
  31. package/lib/components/SPortalSnackbars.vue +9 -24
  32. package/lib/components/SSheet.vue +10 -23
  33. package/lib/components/SSheetFooter.vue +0 -2
  34. package/lib/components/SSheetFooterAction.vue +9 -14
  35. package/lib/components/SSheetFooterActions.vue +1 -3
  36. package/lib/components/SSheetHeader.vue +9 -24
  37. package/lib/components/SSheetHeaderTitle.vue +1 -3
  38. package/lib/components/SSheetMedium.vue +13 -25
  39. package/lib/components/SSnackbar.vue +18 -28
  40. package/lib/components/icons/SIconSend.vue +5 -0
  41. package/lib/composables/Dialog.ts +9 -17
  42. package/lib/composables/Dropdown.ts +1 -1
  43. package/lib/composables/{Menu.ts → Flyout.ts} +11 -4
  44. package/lib/composables/Form.ts +42 -44
  45. package/lib/composables/Modal.ts +9 -9
  46. package/lib/composables/Snackbar.ts +18 -0
  47. package/lib/composables/Validation.ts +28 -0
  48. package/lib/mixins/Sheet.ts +3 -3
  49. package/lib/store/Sefirot.ts +8 -13
  50. package/lib/store/dialog/index.ts +20 -10
  51. package/lib/store/modal/index.ts +11 -13
  52. package/lib/store/snackbars/index.ts +3 -4
  53. package/lib/support/{Util.ts → Utils.ts} +0 -2
  54. package/lib/types/Utils.ts +0 -7
  55. package/lib/types/vue-shims.d.ts +7 -0
  56. package/lib/validation/rules/checked.ts +6 -10
  57. package/lib/validation/rules/fileExtension.ts +9 -9
  58. package/lib/validation/rules/hms.ts +9 -9
  59. package/lib/validation/rules/index.ts +10 -74
  60. package/lib/validation/rules/maxLength.ts +10 -9
  61. package/lib/validation/rules/minLength.ts +12 -0
  62. package/lib/validation/rules/required.ts +2 -10
  63. package/lib/validation/rules/requiredHms.ts +11 -0
  64. package/lib/validation/rules/requiredIf.ts +3 -11
  65. package/lib/validation/rules/requiredYmd.ts +11 -0
  66. package/lib/validation/rules/ymd.ts +11 -0
  67. package/lib/validation/validators/checked.ts +1 -1
  68. package/lib/validation/validators/fileExtension.ts +1 -1
  69. package/lib/validation/validators/hms.ts +5 -5
  70. package/lib/validation/validators/requiredHms.ts +17 -0
  71. package/lib/validation/validators/requiredYmd.ts +7 -0
  72. package/lib/validation/validators/ymd.ts +41 -0
  73. package/package.json +45 -50
  74. package/lib/components/SAction.vue +0 -37
  75. package/lib/components/SActionAvatar.vue +0 -25
  76. package/lib/components/SActionButton.vue +0 -40
  77. package/lib/components/SActionPill.vue +0 -35
  78. package/lib/components/SActionSwitch.vue +0 -37
  79. package/lib/components/SAlert.vue +0 -145
  80. package/lib/components/SButtonGroup.vue +0 -160
  81. package/lib/components/SCard.vue +0 -111
  82. package/lib/components/SCardFooter.vue +0 -74
  83. package/lib/components/SCardHeader.vue +0 -213
  84. package/lib/components/SGrid.vue +0 -237
  85. package/lib/components/SGridActionLink.vue +0 -53
  86. package/lib/components/SGridActionMulti.vue +0 -139
  87. package/lib/components/SGridActionSingle.vue +0 -64
  88. package/lib/components/SHeader.vue +0 -180
  89. package/lib/components/SInputCheckboxes.vue +0 -83
  90. package/lib/components/SInputDate.vue +0 -192
  91. package/lib/components/SInputDay.vue +0 -87
  92. package/lib/components/SInputMonth.vue +0 -86
  93. package/lib/components/SInputSelect.vue +0 -282
  94. package/lib/components/SInputSwitch.vue +0 -212
  95. package/lib/components/SInputSwitches.vue +0 -108
  96. package/lib/components/SInputTime.vue +0 -255
  97. package/lib/components/SInputYear.vue +0 -60
  98. package/lib/components/SMarkdown.vue +0 -56
  99. package/lib/components/SPlaceholderBlank.vue +0 -113
  100. package/lib/components/SPlaceholderImage.vue +0 -83
  101. package/lib/components/SPortalScreens.vue +0 -62
  102. package/lib/components/SProgressBar.vue +0 -89
  103. package/lib/components/SResponsive.vue +0 -46
  104. package/lib/components/SScreen.vue +0 -81
  105. package/lib/components/SStep.vue +0 -107
  106. package/lib/components/SSteps.vue +0 -75
  107. package/lib/components/STag.vue +0 -67
  108. package/lib/components/STooltip.vue +0 -134
  109. package/lib/components/SWindow.vue +0 -158
  110. package/lib/composables/Action.ts +0 -141
  111. package/lib/composables/Alert.ts +0 -50
  112. package/lib/composables/Card.ts +0 -46
  113. package/lib/composables/FormValidation.ts +0 -150
  114. package/lib/composables/Header.ts +0 -72
  115. package/lib/composables/InputDropdown.ts +0 -6
  116. package/lib/composables/Markdown.ts +0 -138
  117. package/lib/composables/Router.ts +0 -20
  118. package/lib/composables/Step.ts +0 -7
  119. package/lib/composables/Store.ts +0 -9
  120. package/lib/composables/Tag.ts +0 -32
  121. package/lib/composables/Tooltip.ts +0 -91
  122. package/lib/composables/Utils.ts +0 -115
  123. package/lib/composables/markdown/LinkPlugin.ts +0 -45
  124. package/lib/compositions/useForm.ts +0 -17
  125. package/lib/compositions/useResizeObserver.ts +0 -25
  126. package/lib/compositions/useTime.ts +0 -26
  127. package/lib/store/alert/index.ts +0 -32
  128. package/lib/store/screen/index.ts +0 -46
  129. package/lib/types/v-calendar.d.ts +0 -5
  130. package/lib/validation/Validation.ts +0 -151
  131. package/lib/validation/rules/day.ts +0 -11
  132. package/lib/validation/rules/email.ts +0 -11
  133. package/lib/validation/rules/every.ts +0 -38
  134. package/lib/validation/rules/include.ts +0 -11
  135. package/lib/validation/rules/includeSome.ts +0 -11
  136. package/lib/validation/rules/integer.ts +0 -11
  137. package/lib/validation/rules/maxValue.ts +0 -11
  138. package/lib/validation/rules/minValue.ts +0 -11
  139. package/lib/validation/rules/month.ts +0 -11
  140. package/lib/validation/rules/not.ts +0 -10
  141. package/lib/validation/rules/regex.ts +0 -11
  142. package/lib/validation/rules/requiredHMS.ts +0 -11
  143. package/lib/validation/rules/requiredMonthDate.ts +0 -11
  144. package/lib/validation/rules/requiredYearMonth.ts +0 -11
  145. package/lib/validation/rules/requiredYearMonthDate.ts +0 -11
  146. package/lib/validation/rules/rule.ts +0 -5
  147. package/lib/validation/rules/sameAs.ts +0 -11
  148. package/lib/validation/rules/url.ts +0 -11
  149. package/lib/validation/rules/validateIf.ts +0 -27
  150. package/lib/validation/rules/year.ts +0 -11
  151. package/lib/validation/rules/yearMonth.ts +0 -11
  152. package/lib/validation/rules/yearMonthDate.ts +0 -11
  153. package/lib/validation/validators/day.ts +0 -29
  154. package/lib/validation/validators/email.ts +0 -5
  155. package/lib/validation/validators/include.ts +0 -5
  156. package/lib/validation/validators/includeSome.ts +0 -5
  157. package/lib/validation/validators/index.ts +0 -51
  158. package/lib/validation/validators/integer.ts +0 -6
  159. package/lib/validation/validators/maxLength.ts +0 -3
  160. package/lib/validation/validators/maxValue.ts +0 -3
  161. package/lib/validation/validators/minValue.ts +0 -3
  162. package/lib/validation/validators/month.ts +0 -3
  163. package/lib/validation/validators/monthDate.ts +0 -20
  164. package/lib/validation/validators/regex.ts +0 -3
  165. package/lib/validation/validators/required.ts +0 -27
  166. package/lib/validation/validators/requiredHMS.ts +0 -17
  167. package/lib/validation/validators/requiredMonthDate.ts +0 -8
  168. package/lib/validation/validators/requiredYearMonth.ts +0 -8
  169. package/lib/validation/validators/requiredYearMonthDate.ts +0 -9
  170. package/lib/validation/validators/sameAs.ts +0 -5
  171. package/lib/validation/validators/url.ts +0 -5
  172. package/lib/validation/validators/year.ts +0 -3
  173. package/lib/validation/validators/yearMonth.ts +0 -20
  174. package/lib/validation/validators/yearMonthDate.ts +0 -21
@@ -1,145 +0,0 @@
1
- <template>
2
- <div class="SAlert" :class="[type]">
3
- <SCard :collapsable="false" :depth="3">
4
- <div class="container">
5
- <div class="icon">
6
- <component :is="icon" class="icon-svg" />
7
- </div>
8
-
9
- <div class="content">
10
- <p class="title">{{ title }}</p>
11
- <p class="text">{{ text }}</p>
12
-
13
- <div class="actions">
14
- <div v-for="(action, index) in actions" :key="index" class="action">
15
- <SButton
16
- size="small"
17
- :type="action.type"
18
- :mode="action.mode"
19
- :icon="action.icon"
20
- :label="action.label"
21
- @click="action.callback"
22
- />
23
- </div>
24
- </div>
25
- </div>
26
- </div>
27
- </SCard>
28
- </div>
29
- </template>
30
-
31
- <script lang="ts">
32
- import { PropType, defineComponent, computed } from '@vue/composition-api'
33
- import { Action, AlertMode, AlertModes } from '../composables/Alert'
34
- import SIconInfo from './icons/SIconInfo.vue'
35
- import SIconCheckCircle from './icons/SIconCheckCircle.vue'
36
- import SIconWarning from './icons/SIconWarning.vue'
37
- import SIconXCircle from './icons/SIconXCircle.vue'
38
- import SButton from './SButton.vue'
39
- import SCard from './SCard.vue'
40
-
41
- export default defineComponent({
42
- components: {
43
- SButton,
44
- SCard
45
- },
46
-
47
- props: {
48
- type: { type: String as PropType<AlertMode>, default: AlertModes.Info },
49
- title: { type: String, default: null },
50
- text: { type: String, default: null },
51
- actions: { type: Array as PropType<Action[]>, default: () => [] }
52
- },
53
-
54
- setup(props) {
55
- const icon = computed(() => {
56
- switch (props.type) {
57
- case AlertModes.Info:
58
- return SIconInfo
59
- case AlertModes.Success:
60
- return SIconCheckCircle
61
- case AlertModes.Warning:
62
- return SIconWarning
63
- case AlertModes.Danger:
64
- return SIconXCircle
65
- }
66
- })
67
-
68
- return {
69
- icon
70
- }
71
- }
72
- })
73
- </script>
74
-
75
- <style lang="postcss" scoped>
76
- @import "@/assets/styles/variables";
77
-
78
- .SAlert {
79
- margin: 64px 16px;
80
- border-radius: 8px;
81
- max-width: 512px;
82
-
83
- @media (min-width: 544px) {
84
- margin: 64px auto;
85
- }
86
- }
87
-
88
- .SAlert.info .icon-svg { fill: var(--c-info); }
89
- .SAlert.success .icon-svg { fill: var(--c-success); }
90
- .SAlert.warning .icon-svg { fill: var(--c-warning); }
91
- .SAlert.danger .icon-svg { fill: var(--c-danger); }
92
-
93
- .container {
94
- @media (min-width: 544px) {
95
- display: flex;
96
- }
97
- }
98
-
99
- .icon {
100
- padding: 16px 16px 8px;
101
-
102
- @media (min-width: 544px) {
103
- display: flex;
104
- justify-content: center;
105
- align-items: center;
106
- flex-shrink: 0;
107
- padding: 0;
108
- width: 64px;
109
- height: 64px;
110
- }
111
- }
112
-
113
- .icon-svg {
114
- width: 24px;
115
- height: 24px;
116
- }
117
-
118
- .content {
119
- padding: 0 16px 16px;
120
-
121
- @media (min-width: 544px) {
122
- flex-grow: 1;
123
- padding: 20px 24px 20px 0;
124
- }
125
- }
126
-
127
- .title {
128
- font-size: 16px;
129
- font-weight: 500;
130
- }
131
-
132
- .text {
133
- font-size: 14px;
134
- }
135
-
136
- .actions {
137
- display: flex;
138
- justify-content: flex-end;
139
- padding-top: 16px;
140
- }
141
-
142
- .action + .action {
143
- padding-left: 8px;
144
- }
145
- </style>
@@ -1,160 +0,0 @@
1
- <template>
2
- <div class="SButtonGroup" :class="classes">
3
- <button
4
- v-for="item in items"
5
- :key="item.value"
6
- class="button"
7
- :class="getButtonClasses(item)"
8
- @click="handleClick(item.value)"
9
- >
10
- <span class="content">
11
- {{ item.label }}
12
- </span>
13
- </button>
14
- </div>
15
- </template>
16
-
17
- <script lang="ts">
18
- import { PropType, defineComponent, computed } from '@vue/composition-api'
19
-
20
- interface ButtonGroupItem {
21
- label: string
22
- value: string
23
- mode: Mode
24
- }
25
-
26
- type Mode = 'neutral' | 'info' | 'success' | 'warning' | 'danger'
27
- type Size = 'mini' | 'small' | 'medium' | 'large' | 'jumbo'
28
-
29
- export default defineComponent({
30
- model: {
31
- prop: 'value',
32
- event: 'change'
33
- },
34
-
35
- props: {
36
- items: { type: Array as PropType<ButtonGroupItem[]>, required: true },
37
- size: { type: String as PropType<Size>, default: 'medium' },
38
- value: { type: String, default: null }
39
- },
40
-
41
- setup(props, { emit }) {
42
- const classes = computed(() => [props.size])
43
-
44
- function getButtonClasses(button: ButtonGroupItem) {
45
- return [
46
- { active: button.value === props.value },
47
- button.mode ?? 'neutral'
48
- ]
49
- }
50
-
51
- function handleClick(value: string) {
52
- emit('change', value)
53
- }
54
-
55
- return {
56
- classes,
57
- getButtonClasses,
58
- handleClick
59
- }
60
- }
61
- })
62
- </script>
63
-
64
- <style lang="postcss" scoped>
65
- .SButtonGroup {
66
- display: flex;
67
- border: 1px solid var(--c-divider);
68
- border-radius: 4px;
69
- overflow: hidden;
70
- }
71
-
72
- .SButtonGroup.mini {
73
- height: 28px;
74
-
75
- .button {
76
- padding: 0 8px;
77
- height: 28px;
78
- font-size: 12px;
79
- font-weight: 500;
80
- }
81
- }
82
-
83
- .SButtonGroup.small {
84
- height: 32px;
85
-
86
- .button {
87
- padding: 0 10px;
88
- height: 32px;
89
- font-size: 12px;
90
- font-weight: 500;
91
- }
92
- }
93
-
94
- .SButtonGroup.medium {
95
- height: 40px;
96
-
97
- .button {
98
- padding: 0 12px;
99
- height: 40px;
100
- font-size: 13px;
101
- font-weight: 500;
102
- }
103
- }
104
-
105
- .SButtonGroup.large {
106
- height: 48px;
107
-
108
- .button {
109
- padding: 0 14px;
110
- height: 48px;
111
- font-size: 14px;
112
- font-weight: 500;
113
- }
114
- }
115
-
116
- .SButtonGroup.jumbo {
117
- height: 64px;
118
-
119
- .button {
120
- padding: 0 24px;
121
- height: 64px;
122
- font-size: 14px;
123
- font-weight: 500;
124
- }
125
- }
126
-
127
- .button {
128
- border-left: 1px solid transparent;
129
- letter-spacing: .4px;
130
- color: var(--c-text-2);
131
- white-space: nowrap;
132
- transition: color .25s, background-color .25s;
133
-
134
- &:hover {
135
- color: var(--c-text-1);
136
- }
137
- }
138
-
139
- .button:not(:first-child) {
140
- border-left: 1px solid var(--c-divider);
141
- }
142
-
143
- .button.active {
144
- color: var(--c-text-dark-1);
145
- }
146
-
147
- .button.neutral.active { background-color: var(--c-black); }
148
- .button.info.active { background-color: var(--c-info); }
149
- .button.success.active { background-color: var(--c-success); }
150
- .button.warning.active { background-color: var(--c-warning); }
151
- .button.danger.active { background-color: var(--c-danger); }
152
-
153
- .content {
154
- display: flex;
155
- justify-content: center;
156
- align-items: center;
157
- width: 100%;
158
- height: 100%;
159
- }
160
- </style>
@@ -1,111 +0,0 @@
1
- <template>
2
- <div class="SCard" :class="classes">
3
- <div v-if="header" class="header">
4
- <SCardHeader
5
- :is-collapsed="isCollapsed"
6
- :title="header.title"
7
- :actions="header.actions"
8
- :mode="header.mode"
9
- :collapsable="collapsable"
10
- @collapse="toggleCollapse"
11
- />
12
- </div>
13
-
14
- <div class="content">
15
- <slot />
16
- </div>
17
-
18
- <div v-if="showFooter" class="footer">
19
- <SCardFooter :actions="footer.actions" />
20
- </div>
21
- </div>
22
- </template>
23
-
24
- <script lang="ts">
25
- import { PropType, defineComponent, ref, computed } from '@vue/composition-api'
26
- import { Header, Footer, Mode } from '../composables/Card'
27
- import { get } from '../composables/Utils'
28
- import SCardHeader from './SCardHeader.vue'
29
- import SCardFooter from './SCardFooter.vue'
30
-
31
- export default defineComponent({
32
- components: {
33
- SCardHeader,
34
- SCardFooter
35
- },
36
-
37
- props: {
38
- header: { type: Object as PropType<Header>, default: null },
39
- footer: { type: Object as PropType<Footer>, default: null },
40
- mode: { type: String as PropType<Mode>, default: 'neutral' },
41
- round: { type: Number, default: 8 },
42
- depth: { type: Number, default: 0 },
43
- collapsable: { type: Boolean, default: true }
44
- },
45
-
46
- setup(props) {
47
- const isCollapsed = ref(false)
48
- const showFooter = computed(() => {
49
- const actions = get(props.footer?.actions) ?? []
50
-
51
- return actions.length > 0
52
- })
53
-
54
- const classes = computed(() => [
55
- { collapsed: isCollapsed.value },
56
- props.mode,
57
- `round-${props.round}`,
58
- `depth-${props.depth}`
59
- ])
60
-
61
- function toggleCollapse(): void {
62
- isCollapsed.value = !isCollapsed.value
63
- }
64
-
65
- return {
66
- isCollapsed,
67
- showFooter,
68
- classes,
69
- toggleCollapse
70
- }
71
- }
72
- })
73
- </script>
74
-
75
- <style lang="postcss" scoped>
76
- @import "@/assets/styles/variables";
77
-
78
- .SCard {
79
- border: 1px solid transparent;
80
- background-color: var(--card-bg);
81
- }
82
-
83
- .SCard.neutral { border-color: var(--c-divider-light); }
84
- .SCard.info { border-color: var(--c-info); }
85
- .SCard.success { border-color: var(--c-success); }
86
- .SCard.warning { border-color: var(--c-warning); }
87
- .SCard.danger { border-color: var(--c-danger); }
88
-
89
- .SCard.collapsed {
90
- height: 48px;
91
- overflow: hidden;
92
- }
93
-
94
- .SCard.round-4 { border-radius: 4px; }
95
- .SCard.round-8 { border-radius: 8px; }
96
-
97
- .SCard.depth-0 { box-shadow: none; }
98
- .SCard.depth-1 { box-shadow: var(--card-shadow-depth-1); }
99
- .SCard.depth-2 { box-shadow: var(--card-shadow-depth-2); }
100
- .SCard.depth-3 { box-shadow: var(--card-shadow-depth-3); }
101
- .SCard.depth-4 { box-shadow: var(--card-shadow-depth-4); }
102
- .SCard.depth-5 { box-shadow: var(--card-shadow-depth-5); }
103
-
104
- .content {
105
- position: relative;
106
- }
107
-
108
- .footer {
109
- overflow: hidden;
110
- }
111
- </style>
@@ -1,74 +0,0 @@
1
- <template>
2
- <div class="SCardFooter" :class="classes">
3
- <div v-if="unwrappedActions.length > 0" class="actions">
4
- <div v-for="(action, index) in unwrappedActions" :key="index" class="action">
5
- <SButton
6
- size="small"
7
- :type="action.type"
8
- :mode="action.mode"
9
- :icon="action.icon"
10
- :label="action.label"
11
- block
12
- @click="action.callback ? action.callback() : () => {}"
13
- />
14
- </div>
15
- </div>
16
- </div>
17
- </template>
18
-
19
- <script lang="ts">
20
- import { defineComponent, PropType, computed } from '@vue/composition-api'
21
- import { Refish, get } from '../composables/Utils'
22
- import { Action } from '../composables/Card'
23
- import SButton from './SButton.vue'
24
-
25
- export default defineComponent({
26
- components: {
27
- SButton
28
- },
29
-
30
- props: {
31
- actions: { type: [Object, Array] as PropType<Refish<Action[]>>, required: true },
32
- round: { type: Number, default: 8 }
33
- },
34
-
35
- setup(props) {
36
- const classes = computed(() => [
37
- `round-${props.round}`
38
- ])
39
-
40
- const unwrappedActions = computed(() => get(props.actions))
41
-
42
- return {
43
- classes,
44
- unwrappedActions
45
- }
46
- }
47
- })
48
- </script>
49
-
50
- <style lang="postcss" scoped>
51
- @import "@/assets/styles/variables";
52
-
53
- .SCardFooter {
54
- border-top: 1px solid var(--c-divider-light);
55
- padding: 16px 16px 15px;
56
- background-color: var(--card-bg);
57
- }
58
-
59
- .SCardFooter.round-4 { border-radius: 0 0 4px 4px; }
60
- .SCardFooter.round-8 { border-radius: 0 0 8px 8px; }
61
-
62
- .actions {
63
- display: flex;
64
- justify-content: flex-end;
65
- }
66
-
67
- .action {
68
- min-width: 96px;
69
- }
70
-
71
- .action + .action {
72
- margin-left: 8px;
73
- }
74
- </style>
@@ -1,213 +0,0 @@
1
- <template>
2
- <div class="SCardHeader" :class="classes">
3
- <div class="title">
4
- <p v-if="title" class="title-text">{{ title }}</p>
5
- </div>
6
-
7
- <div class="actions">
8
- <template v-if="unwrapedActions.length > 0">
9
- <template v-for="(action, index) in unwrapedActions">
10
- <SToolTip :key="index" :text="action.disabled">
11
- <component
12
- :is="action.link ? 'a' : 'button'"
13
- class="action"
14
- :class="[action.mode || 'neutral', { disabled: action.disabled }]"
15
- :href="action.link ? action.link : null"
16
- @click.prevent="handleCallback(action)"
17
- >
18
- <component :is="getIcon(action.icon, !!action.disabled)" class="action-icon" />
19
- </component>
20
- </SToolTip>
21
- </template>
22
- </template>
23
-
24
- <div v-if="collapsable" class="action action-collapse">
25
- <button class="collapse" @click="$emit('collapse')">
26
- <SIconChevronDown class="collapse-icon" />
27
- </button>
28
- </div>
29
- </div>
30
- </div>
31
- </template>
32
-
33
- <script lang="ts">
34
- import { PropType, defineComponent, computed } from '@vue/composition-api'
35
- import { useRouter } from '../composables/Router'
36
- import { Refish, get } from '../composables/Utils'
37
- import { Action, ActionIconType, Mode } from '../composables/Card'
38
- import SIconPlus from './icons/SIconPlus.vue'
39
- import SIconPlusOff from './icons/SIconPlusOff.vue'
40
- import SIconEdit3 from './icons/SIconEdit3.vue'
41
- import SIconEdit3Off from './icons/SIconEdit3Off.vue'
42
- import SIconTrash2 from './icons/SIconTrash2.vue'
43
- import SIconTrash2Off from './icons/SIconTrash2Off.vue'
44
- import SIconChevronDown from './icons/SIconChevronDown.vue'
45
- import SToolTip from './STooltip.vue'
46
-
47
- export default defineComponent({
48
- components: {
49
- SIconChevronDown,
50
- SToolTip
51
- },
52
-
53
- props: {
54
- isCollapsed: { type: Boolean, required: true },
55
- title: { type: String, default: null },
56
- actions: { type: [Array, Object] as PropType<Refish<Action[]>>, default: () => [] },
57
- mode: { type: String as PropType<Mode>, default: 'neutral' },
58
- round: { type: Number, default: 8 },
59
- collapsable: { type: Boolean, required: true }
60
- },
61
-
62
- setup(props) {
63
- const router = useRouter()
64
-
65
- const classes = computed(() => [
66
- { collapsed: props.isCollapsed },
67
- props.mode,
68
- `round-${props.round}`
69
- ])
70
-
71
- const unwrapedActions = computed(() => get(props.actions))
72
-
73
- function getIcon(icon: ActionIconType | object, disabled: boolean) {
74
- if (typeof icon === 'object') {
75
- return icon
76
- }
77
-
78
- if (icon === 'plus') {
79
- return disabled ? SIconPlusOff : SIconPlus
80
- }
81
-
82
- if (icon === 'edit-3') {
83
- return disabled ? SIconEdit3Off : SIconEdit3
84
- }
85
-
86
- if (icon === 'trash-2') {
87
- return disabled ? SIconTrash2Off : SIconTrash2
88
- }
89
-
90
- throw new Error(`[sefirot] Invalid icon type: ${icon}.`)
91
- }
92
-
93
- function handleCallback(action: Action): void {
94
- if (action.disabled) {
95
- return
96
- }
97
-
98
- if (action.link) {
99
- router.push(action.link)
100
- return
101
- }
102
-
103
- action.callback?.()
104
- }
105
-
106
- return {
107
- classes,
108
- unwrapedActions,
109
- getIcon,
110
- handleCallback
111
- }
112
- }
113
- })
114
- </script>
115
-
116
- <style lang="postcss" scoped>
117
- @import "@/assets/styles/variables";
118
-
119
- .SCardHeader {
120
- display: flex;
121
- padding: 8px 8px 7px 16px;
122
- border-bottom: 1px solid var(--c-divider-light);
123
- background-color: var(--card-bg-mute);
124
- }
125
-
126
- .SCardHeader.collapsed {
127
- border-bottom-color: transparent;
128
- }
129
-
130
- .SCardHeader.collapsed .collapse {
131
- transform: rotate(0);
132
- }
133
-
134
- .SCardHeader.collapsed .collapse-icon {
135
- transform: translateY(1px);
136
- }
137
-
138
- .SCardHeader.round-0 { border-radius: none; }
139
- .SCardHeader.round-4 { border-radius: 4px 4px 0 0; }
140
- .SCardHeader.round-8 { border-radius: 8px 8px 0 0; }
141
-
142
- .title {
143
- flex-grow: 1;
144
- }
145
-
146
- .title-text {
147
- line-height: 32px;
148
- font-size: 14px;
149
- font-weight: 500;
150
- }
151
-
152
- .actions {
153
- display: flex;
154
- }
155
-
156
- .action {
157
- display: flex;
158
- justify-content: center;
159
- align-items: center;
160
- flex-shrink: 0;
161
- border-radius: 4px;
162
- width: 32px;
163
- height: 32px;
164
- color: var(--c-text-2);
165
- cursor: pointer;
166
- transition: color .25s, background-color .25s;
167
-
168
- &:hover {
169
- background-color: var(--c-gray-light-4);
170
- }
171
- }
172
-
173
- .action.neutral:hover { color: var(--c-text-1); }
174
- .action.info:hover { color: var(--c-info); }
175
- .action.success:hover { color: var(--c-success); }
176
- .action.warning:hover { color: var(--c-warning); }
177
- .action.danger:hover { color: var(--c-danger); }
178
-
179
- .action.disabled:hover {
180
- color: var(--c-text-2);
181
- background-color: transparent;
182
- cursor: not-allowed;
183
- }
184
-
185
- .action-icon {
186
- width: 16px;
187
- height: 16px;
188
- fill: currentColor;
189
- }
190
-
191
- .collapse {
192
- display: flex;
193
- justify-content: center;
194
- align-items: center;
195
- border-radius: 4px;
196
- width: 32px;
197
- height: 32px;
198
- color: var(--c-text-3);
199
- transform: rotate(180deg);
200
- transition: color .25s, background-color .25s;
201
-
202
- &:hover {
203
- color: var(--c-text-2);
204
- background-color: var(--c-gray-light-4);
205
- }
206
- }
207
-
208
- .collapse-icon {
209
- width: 20px;
210
- height: 20px;
211
- fill: currentColor;
212
- }
213
- </style>