@umbra.ui/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/controls/Dropdown/types.d.ts +5 -0
- package/dist/components/controls/Dropdown/types.d.ts.map +1 -0
- package/dist/components/controls/Dropdown/types.js +1 -0
- package/dist/components/controls/SegmentedControl/types.d.ts +6 -0
- package/dist/components/controls/SegmentedControl/types.d.ts.map +1 -0
- package/dist/components/controls/SegmentedControl/types.js +1 -0
- package/dist/components/dialogs/Alert/types.d.ts +7 -0
- package/dist/components/dialogs/Alert/types.d.ts.map +1 -0
- package/dist/components/dialogs/Alert/types.js +1 -0
- package/dist/components/dialogs/Toast/types.d.ts +34 -0
- package/dist/components/dialogs/Toast/types.d.ts.map +1 -0
- package/dist/components/dialogs/Toast/types.js +10 -0
- package/dist/components/dialogs/Toast/useToast.d.ts +36 -0
- package/dist/components/dialogs/Toast/useToast.d.ts.map +1 -0
- package/dist/components/dialogs/Toast/useToast.js +90 -0
- package/dist/components/indicators/Tooltip/tooltip.d.ts +3 -0
- package/dist/components/indicators/Tooltip/tooltip.d.ts.map +1 -0
- package/dist/components/indicators/Tooltip/tooltip.js +33 -0
- package/dist/components/indicators/Tooltip/types.d.ts +14 -0
- package/dist/components/indicators/Tooltip/types.d.ts.map +1 -0
- package/dist/components/indicators/Tooltip/types.js +1 -0
- package/dist/components/indicators/Tooltip/useTooltip.d.ts +18 -0
- package/dist/components/indicators/Tooltip/useTooltip.d.ts.map +1 -0
- package/dist/components/indicators/Tooltip/useTooltip.js +57 -0
- package/dist/components/inputs/Tags/tag-bar-styles.d.ts +14 -0
- package/dist/components/inputs/Tags/tag-bar-styles.d.ts.map +1 -0
- package/dist/components/inputs/Tags/tag-bar-styles.js +313 -0
- package/dist/components/inputs/Tags/types.d.ts +93 -0
- package/dist/components/inputs/Tags/types.d.ts.map +1 -0
- package/dist/components/inputs/Tags/types.js +216 -0
- package/dist/components/inputs/search/types.d.ts +9 -0
- package/dist/components/inputs/search/types.d.ts.map +1 -0
- package/dist/components/inputs/search/types.js +1 -0
- package/dist/components/navigation/adaptive/types.d.ts +16 -0
- package/dist/components/navigation/adaptive/types.d.ts.map +1 -0
- package/dist/components/navigation/adaptive/types.js +1 -0
- package/dist/components/navigation/adaptive/useAdaptiveLayout.d.ts +27 -0
- package/dist/components/navigation/adaptive/useAdaptiveLayout.d.ts.map +1 -0
- package/dist/components/navigation/adaptive/useAdaptiveLayout.js +40 -0
- package/dist/components/navigation/adaptive/useBreakpoints.d.ts +6 -0
- package/dist/components/navigation/adaptive/useBreakpoints.d.ts.map +1 -0
- package/dist/components/navigation/adaptive/useBreakpoints.js +37 -0
- package/dist/components/navigation/adaptive/useContainerMonitor.d.ts +93 -0
- package/dist/components/navigation/adaptive/useContainerMonitor.d.ts.map +1 -0
- package/dist/components/navigation/adaptive/useContainerMonitor.js +145 -0
- package/dist/components/navigation/adaptive/useViewAnimation.d.ts +31 -0
- package/dist/components/navigation/adaptive/useViewAnimation.d.ts.map +1 -0
- package/dist/components/navigation/adaptive/useViewAnimation.js +591 -0
- package/dist/components/navigation/adaptive/useViewResize.d.ts +52 -0
- package/dist/components/navigation/adaptive/useViewResize.d.ts.map +1 -0
- package/dist/components/navigation/adaptive/useViewResize.js +146 -0
- package/dist/components/navigation/navstack/useNavigationStack.d.ts +25 -0
- package/dist/components/navigation/navstack/useNavigationStack.d.ts.map +1 -0
- package/dist/components/navigation/navstack/useNavigationStack.js +133 -0
- package/dist/components/navigation/slideover/useSlideoverController.d.ts +20 -0
- package/dist/components/navigation/slideover/useSlideoverController.d.ts.map +1 -0
- package/dist/components/navigation/slideover/useSlideoverController.js +267 -0
- package/dist/components/navigation/splitview/useSplitViewController.d.ts +20 -0
- package/dist/components/navigation/splitview/useSplitViewController.d.ts.map +1 -0
- package/dist/components/navigation/splitview/useSplitViewController.js +325 -0
- package/dist/components/navigation/tabcontroller/types.d.ts +21 -0
- package/dist/components/navigation/tabcontroller/types.d.ts.map +1 -0
- package/dist/components/navigation/tabcontroller/types.js +1 -0
- package/dist/components/navigation/tabcontroller/useTabController.d.ts +5 -0
- package/dist/components/navigation/tabcontroller/useTabController.d.ts.map +1 -0
- package/dist/components/navigation/tabcontroller/useTabController.js +10 -0
- package/dist/components/navigation/types.d.ts +8 -0
- package/dist/components/navigation/types.d.ts.map +1 -0
- package/dist/components/navigation/types.js +1 -0
- package/dist/components/pickers/CollectionPicker/types.d.ts +11 -0
- package/dist/components/pickers/CollectionPicker/types.d.ts.map +1 -0
- package/dist/components/pickers/CollectionPicker/types.js +1 -0
- package/dist/components/pickers/ColorPicker/colors.d.ts +13 -0
- package/dist/components/pickers/ColorPicker/colors.d.ts.map +1 -0
- package/dist/components/pickers/ColorPicker/colors.js +266 -0
- package/dist/components/pickers/FilePicker/types.d.ts +10 -0
- package/dist/components/pickers/FilePicker/types.d.ts.map +1 -0
- package/dist/components/pickers/FilePicker/types.js +1 -0
- package/dist/index.d.ts +91 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +196 -0
- package/dist/theme.d.ts +73 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +279 -0
- package/dist/themes/blank.d.ts +7 -0
- package/dist/themes/blank.d.ts.map +1 -0
- package/dist/themes/blank.js +543 -0
- package/dist/themes/crimson-dark.d.ts +4 -0
- package/dist/themes/crimson-dark.d.ts.map +1 -0
- package/dist/themes/crimson-dark.js +552 -0
- package/dist/themes/cyan-light.d.ts +4 -0
- package/dist/themes/cyan-light.d.ts.map +1 -0
- package/dist/themes/cyan-light.js +552 -0
- package/dist/themes/dark.d.ts +4 -0
- package/dist/themes/dark.d.ts.map +1 -0
- package/dist/themes/dark.js +551 -0
- package/dist/themes/gold-dark.d.ts +4 -0
- package/dist/themes/gold-dark.d.ts.map +1 -0
- package/dist/themes/gold-dark.js +552 -0
- package/dist/themes/grass-dark.d.ts +4 -0
- package/dist/themes/grass-dark.d.ts.map +1 -0
- package/dist/themes/grass-dark.js +552 -0
- package/dist/themes/indigo.d.ts +4 -0
- package/dist/themes/indigo.d.ts.map +1 -0
- package/dist/themes/indigo.js +552 -0
- package/dist/themes/light.d.ts +4 -0
- package/dist/themes/light.d.ts.map +1 -0
- package/dist/themes/light.js +551 -0
- package/dist/themes/orange-dark.d.ts +4 -0
- package/dist/themes/orange-dark.d.ts.map +1 -0
- package/dist/themes/orange-dark.js +551 -0
- package/dist/themes/orange-light.d.ts +4 -0
- package/dist/themes/orange-light.d.ts.map +1 -0
- package/dist/themes/orange-light.js +551 -0
- package/package.json +62 -0
- package/src/components/controls/Button/Button.vue +417 -0
- package/src/components/controls/Button/README.md +348 -0
- package/src/components/controls/Button/theme.css +200 -0
- package/src/components/controls/Checkbox/Checkbox.vue +164 -0
- package/src/components/controls/Checkbox/README.md +441 -0
- package/src/components/controls/Checkbox/theme.css +36 -0
- package/src/components/controls/Dropdown/Dropdown.vue +476 -0
- package/src/components/controls/Dropdown/README.md +370 -0
- package/src/components/controls/Dropdown/theme.css +50 -0
- package/src/components/controls/Dropdown/types.ts +6 -0
- package/src/components/controls/IconButton/IconButton.vue +267 -0
- package/src/components/controls/IconButton/README.md +502 -0
- package/src/components/controls/IconButton/theme.css +89 -0
- package/src/components/controls/Radio/README.md +591 -0
- package/src/components/controls/Radio/Radio.vue +89 -0
- package/src/components/controls/Radio/theme.css +14 -0
- package/src/components/controls/RangeSlider/README.md +608 -0
- package/src/components/controls/RangeSlider/RangeSlider.vue +535 -0
- package/src/components/controls/RangeSlider/theme.css +80 -0
- package/src/components/controls/SegmentedControl/README.md +587 -0
- package/src/components/controls/SegmentedControl/SegmentedControl.vue +284 -0
- package/src/components/controls/SegmentedControl/theme.css +60 -0
- package/src/components/controls/SegmentedControl/types.ts +5 -0
- package/src/components/controls/Slider/README.md +627 -0
- package/src/components/controls/Slider/Slider.vue +260 -0
- package/src/components/controls/Slider/theme.css +74 -0
- package/src/components/controls/Stepper/README.md +601 -0
- package/src/components/controls/Stepper/Stepper.vue +103 -0
- package/src/components/controls/Stepper/theme.css +53 -0
- package/src/components/controls/Switch/README.md +667 -0
- package/src/components/controls/Switch/Switch.vue +127 -0
- package/src/components/controls/Switch/theme.css +42 -0
- package/src/components/dialogs/Alert/Alert.vue +218 -0
- package/src/components/dialogs/Alert/README.md +450 -0
- package/src/components/dialogs/Alert/theme.css +44 -0
- package/src/components/dialogs/Alert/types.ts +11 -0
- package/src/components/dialogs/Toast/README.md +522 -0
- package/src/components/dialogs/Toast/Toast.vue +296 -0
- package/src/components/dialogs/Toast/ToastContainer.vue +330 -0
- package/src/components/dialogs/Toast/theme.css +44 -0
- package/src/components/dialogs/Toast/types.ts +46 -0
- package/src/components/dialogs/Toast/useToast.ts +127 -0
- package/src/components/indicators/ProgressBar/ProgressBar.vue +98 -0
- package/src/components/indicators/ProgressBar/README.md +744 -0
- package/src/components/indicators/ProgressBar/theme.css +36 -0
- package/src/components/indicators/Tooltip/README.md +723 -0
- package/src/components/indicators/Tooltip/TooltipProvider.vue +142 -0
- package/src/components/indicators/Tooltip/theme.css +18 -0
- package/src/components/indicators/Tooltip/tooltip.ts +48 -0
- package/src/components/indicators/Tooltip/types.ts +15 -0
- package/src/components/indicators/Tooltip/useTooltip.ts +71 -0
- package/src/components/inputs/AutogrowTextView/AutogrowTextView.vue +110 -0
- package/src/components/inputs/AutogrowTextView/README.md +643 -0
- package/src/components/inputs/AutogrowTextView/theme.css +28 -0
- package/src/components/inputs/InputCard/InputCard.vue +600 -0
- package/src/components/inputs/InputCard/README.md +636 -0
- package/src/components/inputs/InputEmail/InputEmail.vue +698 -0
- package/src/components/inputs/InputEmail/README.md +764 -0
- package/src/components/inputs/InputNumber/InputNumber.vue +300 -0
- package/src/components/inputs/InputNumber/README.md +749 -0
- package/src/components/inputs/InputPhone/InputPhone.vue +645 -0
- package/src/components/inputs/InputPhone/README.md +636 -0
- package/src/components/inputs/InputSecure/InputSecure.vue +646 -0
- package/src/components/inputs/InputSecure/README.md +771 -0
- package/src/components/inputs/InputText/InputText.vue +225 -0
- package/src/components/inputs/InputText/README.md +844 -0
- package/src/components/inputs/OTP/OTP.vue +349 -0
- package/src/components/inputs/OTP/README.md +736 -0
- package/src/components/inputs/OTP/theme.css +50 -0
- package/src/components/inputs/StringCapture/README.md +718 -0
- package/src/components/inputs/StringCapture/StringCapture.vue +315 -0
- package/src/components/inputs/StringCapture/theme.css +86 -0
- package/src/components/inputs/Tags/README.md +897 -0
- package/src/components/inputs/Tags/TagBar.vue +793 -0
- package/src/components/inputs/Tags/TagCreation.vue +219 -0
- package/src/components/inputs/Tags/TagPicker.vue +380 -0
- package/src/components/inputs/Tags/tag-bar-styles.ts +354 -0
- package/src/components/inputs/Tags/theme.css +121 -0
- package/src/components/inputs/Tags/types.ts +346 -0
- package/src/components/inputs/search/README.md +759 -0
- package/src/components/inputs/search/SearchBar.vue +394 -0
- package/src/components/inputs/search/SearchResults.vue +310 -0
- package/src/components/inputs/search/theme.css +187 -0
- package/src/components/inputs/search/types.ts +8 -0
- package/src/components/inputs/theme.css +102 -0
- package/src/components/menus/ActionMenu/ActionMenu.vue +383 -0
- package/src/components/menus/ActionMenu/README.md +825 -0
- package/src/components/menus/ActionMenu/theme.css +93 -0
- package/src/components/models/Popover/Popover.vue +551 -0
- package/src/components/models/Popover/README.md +885 -0
- package/src/components/models/Popover/theme.css +52 -0
- package/src/components/models/Sheet/README.md +1159 -0
- package/src/components/models/Sheet/Sheet.vue +465 -0
- package/src/components/models/Sheet/theme.css +72 -0
- package/src/components/models/Sidebar/README.md +1228 -0
- package/src/components/models/Sidebar/Sidebar.vue +480 -0
- package/src/components/models/Sidebar/theme.css +90 -0
- package/src/components/navigation/adaptive/AdaptiveLayout.vue +779 -0
- package/src/components/navigation/adaptive/AdaptiveLayoutBreadcrumbs.vue +192 -0
- package/src/components/navigation/adaptive/AdaptiveLayoutMenuButton.vue +149 -0
- package/src/components/navigation/adaptive/README.md +768 -0
- package/src/components/navigation/adaptive/types.ts +19 -0
- package/src/components/navigation/adaptive/useAdaptiveLayout.ts +89 -0
- package/src/components/navigation/adaptive/useBreakpoints.ts +41 -0
- package/src/components/navigation/adaptive/useContainerMonitor.ts +214 -0
- package/src/components/navigation/adaptive/useViewAnimation.ts +721 -0
- package/src/components/navigation/adaptive/useViewResize.ts +211 -0
- package/src/components/navigation/navstack/NavigationStack.vue +180 -0
- package/src/components/navigation/navstack/README.md +994 -0
- package/src/components/navigation/navstack/useNavigationStack.ts +164 -0
- package/src/components/navigation/slideover/README.md +1275 -0
- package/src/components/navigation/slideover/SlideoverController.vue +287 -0
- package/src/components/navigation/slideover/useSlideoverController.ts +320 -0
- package/src/components/navigation/splitview/README.md +1115 -0
- package/src/components/navigation/splitview/SplitViewController.vue +176 -0
- package/src/components/navigation/splitview/useSplitViewController.ts +388 -0
- package/src/components/navigation/tabcontroller/README.md +919 -0
- package/src/components/navigation/tabcontroller/TabController.vue +307 -0
- package/src/components/navigation/tabcontroller/TabItem.vue +57 -0
- package/src/components/navigation/tabcontroller/types.ts +24 -0
- package/src/components/navigation/tabcontroller/useTabController.ts +18 -0
- package/src/components/navigation/theme.css +91 -0
- package/src/components/navigation/types.ts +7 -0
- package/src/components/pickers/CollectionPicker/CollectionPicker.vue +398 -0
- package/src/components/pickers/CollectionPicker/README.md +1115 -0
- package/src/components/pickers/CollectionPicker/theme.css +14 -0
- package/src/components/pickers/CollectionPicker/types.ts +11 -0
- package/src/components/pickers/ColorPicker/ColorPicker.vue +376 -0
- package/src/components/pickers/ColorPicker/README.md +1439 -0
- package/src/components/pickers/ColorPicker/colors.ts +299 -0
- package/src/components/pickers/ColorPicker/theme.css +32 -0
- package/src/components/pickers/DatePicker/DatePicker.vue +660 -0
- package/src/components/pickers/DatePicker/README.md +1195 -0
- package/src/components/pickers/DatePicker/theme.css +22 -0
- package/src/components/pickers/FilePicker/FilePicker.vue +534 -0
- package/src/components/pickers/FilePicker/README.md +1542 -0
- package/src/components/pickers/FilePicker/theme.css +48 -0
- package/src/components/pickers/FilePicker/types.ts +10 -0
- package/src/components/pickers/IconPicker/IconPicker.vue +327 -0
- package/src/components/pickers/IconPicker/README.md +1161 -0
- package/src/components/pickers/IconPicker/theme.css +28 -0
- package/src/components/pickers/theme.css +82 -0
- package/src/components/views/MarkdownViewer/MarkdownViewer.vue +442 -0
- package/src/components/views/MarkdownViewer/README.md +833 -0
- package/src/components/views/MarkdownViewer/theme.css +130 -0
- package/src/index.ts +263 -0
- package/src/theme.ts +378 -0
- package/src/themes/crimson-dark.ts +556 -0
- package/src/themes/cyan-light.ts +556 -0
- package/src/themes/dark.ts +557 -0
- package/src/themes/gold-dark.ts +556 -0
- package/src/themes/grass-dark.ts +556 -0
- package/src/themes/indigo.ts +556 -0
- package/src/themes/light.ts +557 -0
- package/src/themes/orange-dark.ts +557 -0
- package/src/themes/orange-light.ts +557 -0
- package/src/vue.d.ts +45 -0
|
@@ -0,0 +1,718 @@
|
|
|
1
|
+
# StringCapture
|
|
2
|
+
|
|
3
|
+
A popover-based text input component built with Vue 3 Composition API and TypeScript. The StringCapture component provides a modal-like interface for capturing text input with a floating popup, overlay, and integrated submit/cancel functionality.
|
|
4
|
+
|
|
5
|
+
## Installation/Import
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { StringCapture } from "@umbra-ui/core";
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Dependencies:**
|
|
12
|
+
|
|
13
|
+
- Vue 3.x
|
|
14
|
+
- @umbra-ui/core (for IconButton component)
|
|
15
|
+
- @floating-ui/vue (for positioning)
|
|
16
|
+
|
|
17
|
+
## Basic Usage
|
|
18
|
+
|
|
19
|
+
```vue
|
|
20
|
+
<script setup lang="ts">
|
|
21
|
+
import { ref } from "vue";
|
|
22
|
+
import { StringCapture, Button } from "@umbra-ui/core";
|
|
23
|
+
|
|
24
|
+
const capturedText = ref("");
|
|
25
|
+
const isOpen = ref(false);
|
|
26
|
+
|
|
27
|
+
const handleSubmit = (value: string) => {
|
|
28
|
+
console.log("Captured text:", value);
|
|
29
|
+
capturedText.value = value;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const handleCancel = () => {
|
|
33
|
+
console.log("Capture cancelled");
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const openCapture = () => {
|
|
37
|
+
isOpen.value = true;
|
|
38
|
+
};
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<template>
|
|
42
|
+
<div>
|
|
43
|
+
<StringCapture
|
|
44
|
+
v-model="capturedText"
|
|
45
|
+
header-label="Enter Your Text"
|
|
46
|
+
placeholder="Type something..."
|
|
47
|
+
@submit="handleSubmit"
|
|
48
|
+
@cancel="handleCancel"
|
|
49
|
+
>
|
|
50
|
+
<Button @click="openCapture">
|
|
51
|
+
{{ capturedText || "Click to enter text" }}
|
|
52
|
+
</Button>
|
|
53
|
+
</StringCapture>
|
|
54
|
+
</div>
|
|
55
|
+
</template>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Props
|
|
59
|
+
|
|
60
|
+
| Prop Name | Type | Required | Default | Description |
|
|
61
|
+
| ------------- | --------- | -------- | ----------------- | ----------------------------------------- |
|
|
62
|
+
| `modelValue` | `string` | No | `""` | The captured text value |
|
|
63
|
+
| `placeholder` | `string` | No | `"Enter text..."` | Placeholder text for the input field |
|
|
64
|
+
| `headerLabel` | `string` | No | `"Enter Text"` | Label displayed in the popup header |
|
|
65
|
+
| `loading` | `boolean` | No | `false` | Whether the component is in loading state |
|
|
66
|
+
|
|
67
|
+
## Events
|
|
68
|
+
|
|
69
|
+
| Event Name | Payload Type | Description |
|
|
70
|
+
| ------------------- | ------------ | ----------------------------------------- |
|
|
71
|
+
| `update:modelValue` | `string` | Emitted when the text value changes |
|
|
72
|
+
| `submit` | `string` | Emitted when the submit button is clicked |
|
|
73
|
+
| `cancel` | `void` | Emitted when the capture is cancelled |
|
|
74
|
+
|
|
75
|
+
## Slots
|
|
76
|
+
|
|
77
|
+
| Slot Name | Description |
|
|
78
|
+
| --------- | ---------------------------------------- |
|
|
79
|
+
| `default` | The trigger element that opens the popup |
|
|
80
|
+
|
|
81
|
+
## Exposed Methods/Refs
|
|
82
|
+
|
|
83
|
+
The StringCapture component exposes the following methods via template refs:
|
|
84
|
+
|
|
85
|
+
| Method Name | Parameters | Description |
|
|
86
|
+
| --------------- | ---------- | ----------------------------------- |
|
|
87
|
+
| `togglePopover` | `()` | Toggles the popup open/closed state |
|
|
88
|
+
|
|
89
|
+
### Example Usage
|
|
90
|
+
|
|
91
|
+
```vue
|
|
92
|
+
<script setup lang="ts">
|
|
93
|
+
import { ref } from "vue";
|
|
94
|
+
import { StringCapture } from "@umbra-ui/core";
|
|
95
|
+
|
|
96
|
+
const stringCaptureRef = ref();
|
|
97
|
+
|
|
98
|
+
const openCapture = () => {
|
|
99
|
+
stringCaptureRef.value?.togglePopover();
|
|
100
|
+
};
|
|
101
|
+
</script>
|
|
102
|
+
|
|
103
|
+
<template>
|
|
104
|
+
<div>
|
|
105
|
+
<StringCapture ref="stringCaptureRef" v-model="capturedText">
|
|
106
|
+
<button @click="openCapture">Open Capture</button>
|
|
107
|
+
</StringCapture>
|
|
108
|
+
</div>
|
|
109
|
+
</template>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## CSS Customization
|
|
113
|
+
|
|
114
|
+
The StringCapture component uses CSS custom properties for theming and customization:
|
|
115
|
+
|
|
116
|
+
### Popup Variables
|
|
117
|
+
|
|
118
|
+
```css
|
|
119
|
+
/* Popup Container */
|
|
120
|
+
--stringcapture-popup-bg: var(--stringcapture-popup-background);
|
|
121
|
+
--stringcapture-popup-border: var(--stringcapture-popup-border-color);
|
|
122
|
+
--stringcapture-popup-shadow: var(--stringcapture-popup-shadow-color);
|
|
123
|
+
--stringcapture-popup-inset-shadow: var(
|
|
124
|
+
--stringcapture-popup-inset-shadow-color
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
/* Header */
|
|
128
|
+
--stringcapture-header-bg: var(--stringcapture-header-background);
|
|
129
|
+
--stringcapture-header-border: var(--stringcapture-header-border-color);
|
|
130
|
+
--stringcapture-header-text: var(--stringcapture-header-text-color);
|
|
131
|
+
|
|
132
|
+
/* Input Container */
|
|
133
|
+
--stringcapture-input-container-bg: var(
|
|
134
|
+
--stringcapture-input-container-background
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
/* Input Field */
|
|
138
|
+
--stringcapture-input-text: var(--stringcapture-input-text-color);
|
|
139
|
+
|
|
140
|
+
/* Overlay */
|
|
141
|
+
--stringcapture-overlay-bg: var(--stringcapture-overlay-background);
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Key Features
|
|
145
|
+
|
|
146
|
+
### Popup Interface
|
|
147
|
+
|
|
148
|
+
- **Floating Popup**: Positioned using Floating UI for optimal placement
|
|
149
|
+
- **Overlay Background**: Semi-transparent overlay that covers the entire screen
|
|
150
|
+
- **Smooth Animations**: Fade-in/out animations for popup and overlay
|
|
151
|
+
- **Responsive Positioning**: Automatically adjusts position based on available space
|
|
152
|
+
|
|
153
|
+
### Input Management
|
|
154
|
+
|
|
155
|
+
- **Auto-focus**: Input field automatically receives focus when opened
|
|
156
|
+
- **Keyboard Navigation**: Enter to submit, Escape to cancel
|
|
157
|
+
- **Submit Button**: Integrated submit button with visual feedback
|
|
158
|
+
- **Input Validation**: Submit button is disabled when input is empty
|
|
159
|
+
|
|
160
|
+
### User Experience
|
|
161
|
+
|
|
162
|
+
- **Click Outside**: Clicking the overlay closes the popup
|
|
163
|
+
- **Escape Key**: Pressing Escape cancels the capture
|
|
164
|
+
- **Enter Key**: Pressing Enter submits the captured text
|
|
165
|
+
- **Visual Feedback**: Submit button opacity changes based on input state
|
|
166
|
+
|
|
167
|
+
### Accessibility
|
|
168
|
+
|
|
169
|
+
- **Focus Management**: Proper focus handling for keyboard navigation
|
|
170
|
+
- **ARIA Support**: Accessible popup interface
|
|
171
|
+
- **Keyboard Navigation**: Full keyboard support
|
|
172
|
+
- **Screen Reader Support**: Proper labeling and announcements
|
|
173
|
+
|
|
174
|
+
## Examples
|
|
175
|
+
|
|
176
|
+
### Basic String Capture
|
|
177
|
+
|
|
178
|
+
```vue
|
|
179
|
+
<script setup lang="ts">
|
|
180
|
+
import { ref } from "vue";
|
|
181
|
+
import { StringCapture, Button } from "@umbra-ui/core";
|
|
182
|
+
|
|
183
|
+
const capturedText = ref("");
|
|
184
|
+
const isEditing = ref(false);
|
|
185
|
+
|
|
186
|
+
const handleSubmit = (value: string) => {
|
|
187
|
+
console.log("Text captured:", value);
|
|
188
|
+
capturedText.value = value;
|
|
189
|
+
isEditing.value = false;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const handleCancel = () => {
|
|
193
|
+
console.log("Capture cancelled");
|
|
194
|
+
isEditing.value = false;
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const startCapture = () => {
|
|
198
|
+
isEditing.value = true;
|
|
199
|
+
};
|
|
200
|
+
</script>
|
|
201
|
+
|
|
202
|
+
<template>
|
|
203
|
+
<div class="basic-capture">
|
|
204
|
+
<h3>Basic String Capture</h3>
|
|
205
|
+
|
|
206
|
+
<StringCapture
|
|
207
|
+
v-model="capturedText"
|
|
208
|
+
header-label="Enter Your Name"
|
|
209
|
+
placeholder="Type your name..."
|
|
210
|
+
@submit="handleSubmit"
|
|
211
|
+
@cancel="handleCancel"
|
|
212
|
+
>
|
|
213
|
+
<Button @click="startCapture">
|
|
214
|
+
{{ capturedText || "Click to enter your name" }}
|
|
215
|
+
</Button>
|
|
216
|
+
</StringCapture>
|
|
217
|
+
|
|
218
|
+
<div v-if="capturedText" class="captured-text">
|
|
219
|
+
<p>
|
|
220
|
+
Captured: <strong>{{ capturedText }}</strong>
|
|
221
|
+
</p>
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
</template>
|
|
225
|
+
|
|
226
|
+
<style module>
|
|
227
|
+
.basic-capture {
|
|
228
|
+
max-width: 400px;
|
|
229
|
+
padding: 2rem;
|
|
230
|
+
border: 1px solid #e0e0e0;
|
|
231
|
+
border-radius: 0.5rem;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.captured-text {
|
|
235
|
+
margin-top: 1rem;
|
|
236
|
+
padding: 1rem;
|
|
237
|
+
background-color: #f8f9fa;
|
|
238
|
+
border-radius: 0.25rem;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.captured-text p {
|
|
242
|
+
margin: 0;
|
|
243
|
+
color: #666;
|
|
244
|
+
}
|
|
245
|
+
</style>
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Inline Text Editing
|
|
249
|
+
|
|
250
|
+
```vue
|
|
251
|
+
<script setup lang="ts">
|
|
252
|
+
import { ref } from "vue";
|
|
253
|
+
import { StringCapture } from "@umbra-ui/core";
|
|
254
|
+
|
|
255
|
+
const editableText = ref("Click to edit this text");
|
|
256
|
+
const isEditing = ref(false);
|
|
257
|
+
|
|
258
|
+
const handleSubmit = (value: string) => {
|
|
259
|
+
editableText.value = value;
|
|
260
|
+
isEditing.value = false;
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
const handleCancel = () => {
|
|
264
|
+
isEditing.value = false;
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
const startEdit = () => {
|
|
268
|
+
isEditing.value = true;
|
|
269
|
+
};
|
|
270
|
+
</script>
|
|
271
|
+
|
|
272
|
+
<template>
|
|
273
|
+
<div class="inline-editing">
|
|
274
|
+
<h3>Inline Text Editing</h3>
|
|
275
|
+
|
|
276
|
+
<div class="editable-content">
|
|
277
|
+
<StringCapture
|
|
278
|
+
v-model="editableText"
|
|
279
|
+
header-label="Edit Text"
|
|
280
|
+
placeholder="Enter new text..."
|
|
281
|
+
@submit="handleSubmit"
|
|
282
|
+
@cancel="handleCancel"
|
|
283
|
+
>
|
|
284
|
+
<div
|
|
285
|
+
class="editable-text"
|
|
286
|
+
@click="startEdit"
|
|
287
|
+
:class="{ editing: isEditing }"
|
|
288
|
+
>
|
|
289
|
+
{{ editableText }}
|
|
290
|
+
</div>
|
|
291
|
+
</StringCapture>
|
|
292
|
+
</div>
|
|
293
|
+
|
|
294
|
+
<p class="instruction">Click on the text above to edit it</p>
|
|
295
|
+
</div>
|
|
296
|
+
</template>
|
|
297
|
+
|
|
298
|
+
<style module>
|
|
299
|
+
.inline-editing {
|
|
300
|
+
max-width: 500px;
|
|
301
|
+
padding: 2rem;
|
|
302
|
+
border: 1px solid #e0e0e0;
|
|
303
|
+
border-radius: 0.5rem;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.editable-content {
|
|
307
|
+
margin: 1rem 0;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.editable-text {
|
|
311
|
+
padding: 0.75rem;
|
|
312
|
+
border: 2px dashed #ddd;
|
|
313
|
+
border-radius: 0.25rem;
|
|
314
|
+
cursor: pointer;
|
|
315
|
+
transition: all 0.2s;
|
|
316
|
+
background-color: #f8f9fa;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.editable-text:hover {
|
|
320
|
+
border-color: #007bff;
|
|
321
|
+
background-color: #e3f2fd;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.editable-text.editing {
|
|
325
|
+
border-color: #007bff;
|
|
326
|
+
background-color: #e3f2fd;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.instruction {
|
|
330
|
+
margin-top: 1rem;
|
|
331
|
+
color: #666;
|
|
332
|
+
font-size: 0.875rem;
|
|
333
|
+
font-style: italic;
|
|
334
|
+
}
|
|
335
|
+
</style>
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Form Integration
|
|
339
|
+
|
|
340
|
+
```vue
|
|
341
|
+
<script setup lang="ts">
|
|
342
|
+
import { ref, computed } from "vue";
|
|
343
|
+
import { StringCapture, Button } from "@umbra-ui/core";
|
|
344
|
+
|
|
345
|
+
interface FormData {
|
|
346
|
+
title: string;
|
|
347
|
+
description: string;
|
|
348
|
+
tags: string;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
const formData = ref<FormData>({
|
|
352
|
+
title: "",
|
|
353
|
+
description: "",
|
|
354
|
+
tags: "",
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
const isFormValid = computed(() => {
|
|
358
|
+
return formData.value.title && formData.value.description;
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
const handleTitleSubmit = (value: string) => {
|
|
362
|
+
formData.value.title = value;
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
const handleDescriptionSubmit = (value: string) => {
|
|
366
|
+
formData.value.description = value;
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
const handleTagsSubmit = (value: string) => {
|
|
370
|
+
formData.value.tags = value;
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
const handleFormSubmit = () => {
|
|
374
|
+
if (isFormValid.value) {
|
|
375
|
+
console.log("Form submitted:", formData.value);
|
|
376
|
+
// Handle form submission
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
</script>
|
|
380
|
+
|
|
381
|
+
<template>
|
|
382
|
+
<div class="form-integration">
|
|
383
|
+
<h3>Form Integration</h3>
|
|
384
|
+
|
|
385
|
+
<form @submit.prevent="handleFormSubmit">
|
|
386
|
+
<div class="form-group">
|
|
387
|
+
<label>Title</label>
|
|
388
|
+
<StringCapture
|
|
389
|
+
v-model="formData.title"
|
|
390
|
+
header-label="Enter Title"
|
|
391
|
+
placeholder="Enter project title..."
|
|
392
|
+
@submit="handleTitleSubmit"
|
|
393
|
+
>
|
|
394
|
+
<div class="form-field">
|
|
395
|
+
{{ formData.title || "Click to enter title" }}
|
|
396
|
+
</div>
|
|
397
|
+
</StringCapture>
|
|
398
|
+
</div>
|
|
399
|
+
|
|
400
|
+
<div class="form-group">
|
|
401
|
+
<label>Description</label>
|
|
402
|
+
<StringCapture
|
|
403
|
+
v-model="formData.description"
|
|
404
|
+
header-label="Enter Description"
|
|
405
|
+
placeholder="Enter project description..."
|
|
406
|
+
@submit="handleDescriptionSubmit"
|
|
407
|
+
>
|
|
408
|
+
<div class="form-field">
|
|
409
|
+
{{ formData.description || "Click to enter description" }}
|
|
410
|
+
</div>
|
|
411
|
+
</StringCapture>
|
|
412
|
+
</div>
|
|
413
|
+
|
|
414
|
+
<div class="form-group">
|
|
415
|
+
<label>Tags (Optional)</label>
|
|
416
|
+
<StringCapture
|
|
417
|
+
v-model="formData.tags"
|
|
418
|
+
header-label="Enter Tags"
|
|
419
|
+
placeholder="Enter tags separated by commas..."
|
|
420
|
+
@submit="handleTagsSubmit"
|
|
421
|
+
>
|
|
422
|
+
<div class="form-field">
|
|
423
|
+
{{ formData.tags || "Click to enter tags" }}
|
|
424
|
+
</div>
|
|
425
|
+
</StringCapture>
|
|
426
|
+
</div>
|
|
427
|
+
|
|
428
|
+
<Button type="submit" :disabled="!isFormValid" class="submit-button">
|
|
429
|
+
Create Project
|
|
430
|
+
</Button>
|
|
431
|
+
</form>
|
|
432
|
+
</div>
|
|
433
|
+
</template>
|
|
434
|
+
|
|
435
|
+
<style module>
|
|
436
|
+
.form-integration {
|
|
437
|
+
max-width: 600px;
|
|
438
|
+
padding: 2rem;
|
|
439
|
+
border: 1px solid #e0e0e0;
|
|
440
|
+
border-radius: 0.5rem;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
.form-group {
|
|
444
|
+
margin-bottom: 1.5rem;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
.form-group label {
|
|
448
|
+
display: block;
|
|
449
|
+
margin-bottom: 0.5rem;
|
|
450
|
+
font-weight: 500;
|
|
451
|
+
color: #333;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
.form-field {
|
|
455
|
+
padding: 0.75rem;
|
|
456
|
+
border: 1px solid #ddd;
|
|
457
|
+
border-radius: 0.25rem;
|
|
458
|
+
cursor: pointer;
|
|
459
|
+
transition: border-color 0.2s;
|
|
460
|
+
background-color: #fff;
|
|
461
|
+
min-height: 2.5rem;
|
|
462
|
+
display: flex;
|
|
463
|
+
align-items: center;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
.form-field:hover {
|
|
467
|
+
border-color: #007bff;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
.submit-button {
|
|
471
|
+
width: 100%;
|
|
472
|
+
padding: 0.75rem;
|
|
473
|
+
background-color: #007bff;
|
|
474
|
+
color: white;
|
|
475
|
+
border: none;
|
|
476
|
+
border-radius: 0.25rem;
|
|
477
|
+
cursor: pointer;
|
|
478
|
+
font-size: 1rem;
|
|
479
|
+
transition: background-color 0.2s;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
.submit-button:hover:not(:disabled) {
|
|
483
|
+
background-color: #0056b3;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
.submit-button:disabled {
|
|
487
|
+
background-color: #6c757d;
|
|
488
|
+
cursor: not-allowed;
|
|
489
|
+
}
|
|
490
|
+
</style>
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
### Quick Actions
|
|
494
|
+
|
|
495
|
+
```vue
|
|
496
|
+
<script setup lang="ts">
|
|
497
|
+
import { ref } from "vue";
|
|
498
|
+
import { StringCapture, Button } from "@umbra-ui/core";
|
|
499
|
+
|
|
500
|
+
const quickActions = ref<string[]>([]);
|
|
501
|
+
const newAction = ref("");
|
|
502
|
+
|
|
503
|
+
const handleAddAction = (value: string) => {
|
|
504
|
+
if (value.trim()) {
|
|
505
|
+
quickActions.value.push(value.trim());
|
|
506
|
+
newAction.value = "";
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
|
|
510
|
+
const removeAction = (index: number) => {
|
|
511
|
+
quickActions.value.splice(index, 1);
|
|
512
|
+
};
|
|
513
|
+
|
|
514
|
+
const clearAllActions = () => {
|
|
515
|
+
quickActions.value = [];
|
|
516
|
+
};
|
|
517
|
+
</script>
|
|
518
|
+
|
|
519
|
+
<template>
|
|
520
|
+
<div class="quick-actions">
|
|
521
|
+
<h3>Quick Actions</h3>
|
|
522
|
+
|
|
523
|
+
<div class="actions-list">
|
|
524
|
+
<div
|
|
525
|
+
v-for="(action, index) in quickActions"
|
|
526
|
+
:key="index"
|
|
527
|
+
class="action-item"
|
|
528
|
+
>
|
|
529
|
+
<span>{{ action }}</span>
|
|
530
|
+
<button @click="removeAction(index)" class="remove-btn">×</button>
|
|
531
|
+
</div>
|
|
532
|
+
</div>
|
|
533
|
+
|
|
534
|
+
<div class="add-action">
|
|
535
|
+
<StringCapture
|
|
536
|
+
v-model="newAction"
|
|
537
|
+
header-label="Add Quick Action"
|
|
538
|
+
placeholder="Enter action name..."
|
|
539
|
+
@submit="handleAddAction"
|
|
540
|
+
>
|
|
541
|
+
<Button class="add-button"> + Add Action </Button>
|
|
542
|
+
</StringCapture>
|
|
543
|
+
</div>
|
|
544
|
+
|
|
545
|
+
<div v-if="quickActions.length > 0" class="actions-controls">
|
|
546
|
+
<Button @click="clearAllActions" class="clear-button"> Clear All </Button>
|
|
547
|
+
</div>
|
|
548
|
+
</div>
|
|
549
|
+
</template>
|
|
550
|
+
|
|
551
|
+
<style module>
|
|
552
|
+
.quick-actions {
|
|
553
|
+
max-width: 500px;
|
|
554
|
+
padding: 2rem;
|
|
555
|
+
border: 1px solid #e0e0e0;
|
|
556
|
+
border-radius: 0.5rem;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
.actions-list {
|
|
560
|
+
margin: 1rem 0;
|
|
561
|
+
display: flex;
|
|
562
|
+
flex-direction: column;
|
|
563
|
+
gap: 0.5rem;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
.action-item {
|
|
567
|
+
display: flex;
|
|
568
|
+
justify-content: space-between;
|
|
569
|
+
align-items: center;
|
|
570
|
+
padding: 0.75rem;
|
|
571
|
+
background-color: #f8f9fa;
|
|
572
|
+
border-radius: 0.25rem;
|
|
573
|
+
border: 1px solid #e9ecef;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
.remove-btn {
|
|
577
|
+
background: none;
|
|
578
|
+
border: none;
|
|
579
|
+
color: #dc3545;
|
|
580
|
+
cursor: pointer;
|
|
581
|
+
font-size: 1.25rem;
|
|
582
|
+
padding: 0.25rem;
|
|
583
|
+
border-radius: 0.25rem;
|
|
584
|
+
transition: background-color 0.2s;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
.remove-btn:hover {
|
|
588
|
+
background-color: #f8d7da;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
.add-action {
|
|
592
|
+
margin: 1rem 0;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
.add-button {
|
|
596
|
+
width: 100%;
|
|
597
|
+
padding: 0.75rem;
|
|
598
|
+
background-color: #28a745;
|
|
599
|
+
color: white;
|
|
600
|
+
border: none;
|
|
601
|
+
border-radius: 0.25rem;
|
|
602
|
+
cursor: pointer;
|
|
603
|
+
font-size: 1rem;
|
|
604
|
+
transition: background-color 0.2s;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
.add-button:hover {
|
|
608
|
+
background-color: #218838;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
.actions-controls {
|
|
612
|
+
margin-top: 1rem;
|
|
613
|
+
text-align: center;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
.clear-button {
|
|
617
|
+
padding: 0.5rem 1rem;
|
|
618
|
+
background-color: #dc3545;
|
|
619
|
+
color: white;
|
|
620
|
+
border: none;
|
|
621
|
+
border-radius: 0.25rem;
|
|
622
|
+
cursor: pointer;
|
|
623
|
+
font-size: 0.875rem;
|
|
624
|
+
transition: background-color 0.2s;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
.clear-button:hover {
|
|
628
|
+
background-color: #c82333;
|
|
629
|
+
}
|
|
630
|
+
</style>
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
### Custom Styling
|
|
634
|
+
|
|
635
|
+
```vue
|
|
636
|
+
<script setup lang="ts">
|
|
637
|
+
import { ref } from "vue";
|
|
638
|
+
import { StringCapture, Button } from "@umbra-ui/core";
|
|
639
|
+
|
|
640
|
+
const customText = ref("");
|
|
641
|
+
|
|
642
|
+
const handleSubmit = (value: string) => {
|
|
643
|
+
customText.value = value;
|
|
644
|
+
};
|
|
645
|
+
</script>
|
|
646
|
+
|
|
647
|
+
<template>
|
|
648
|
+
<div class="custom-styling">
|
|
649
|
+
<h3>Custom Styled String Capture</h3>
|
|
650
|
+
|
|
651
|
+
<StringCapture
|
|
652
|
+
v-model="customText"
|
|
653
|
+
header-label="Custom Styled Input"
|
|
654
|
+
placeholder="Enter text with custom styling..."
|
|
655
|
+
@submit="handleSubmit"
|
|
656
|
+
>
|
|
657
|
+
<Button class="custom-trigger">
|
|
658
|
+
{{ customText || "Custom Styled Button" }}
|
|
659
|
+
</Button>
|
|
660
|
+
</StringCapture>
|
|
661
|
+
</div>
|
|
662
|
+
</template>
|
|
663
|
+
|
|
664
|
+
<style module>
|
|
665
|
+
.custom-styling {
|
|
666
|
+
max-width: 500px;
|
|
667
|
+
padding: 2rem;
|
|
668
|
+
border: 1px solid #e0e0e0;
|
|
669
|
+
border-radius: 0.5rem;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
.custom-trigger {
|
|
673
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
674
|
+
color: white;
|
|
675
|
+
border: none;
|
|
676
|
+
border-radius: 0.5rem;
|
|
677
|
+
padding: 1rem 2rem;
|
|
678
|
+
font-size: 1rem;
|
|
679
|
+
font-weight: 500;
|
|
680
|
+
cursor: pointer;
|
|
681
|
+
transition: transform 0.2s, box-shadow 0.2s;
|
|
682
|
+
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
.custom-trigger:hover {
|
|
686
|
+
transform: translateY(-2px);
|
|
687
|
+
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/* Custom CSS variables for theming */
|
|
691
|
+
.custom-styling {
|
|
692
|
+
--stringcapture-popup-bg: #ffffff;
|
|
693
|
+
--stringcapture-popup-border: 2px solid #667eea;
|
|
694
|
+
--stringcapture-popup-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
|
|
695
|
+
|
|
696
|
+
--stringcapture-header-bg: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
697
|
+
--stringcapture-header-text: #ffffff;
|
|
698
|
+
|
|
699
|
+
--stringcapture-input-container-bg: #f8f9fa;
|
|
700
|
+
--stringcapture-input-text: #333333;
|
|
701
|
+
|
|
702
|
+
--stringcapture-overlay-bg: rgba(102, 126, 234, 0.3);
|
|
703
|
+
}
|
|
704
|
+
</style>
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
## Technical Notes
|
|
708
|
+
|
|
709
|
+
- StringCapture provides a modal-like interface for text input with floating popup
|
|
710
|
+
- Floating UI is used for precise positioning and responsive placement
|
|
711
|
+
- The component uses Vue's Teleport to render the popup outside the component tree
|
|
712
|
+
- Keyboard navigation includes Enter to submit and Escape to cancel
|
|
713
|
+
- Click outside functionality closes the popup via overlay click
|
|
714
|
+
- Smooth animations provide visual feedback for popup show/hide
|
|
715
|
+
- CSS custom properties enable easy theming for light and dark modes
|
|
716
|
+
- The component integrates with IconButton for the submit functionality
|
|
717
|
+
- Focus management ensures proper keyboard navigation
|
|
718
|
+
- TypeScript interfaces ensure type safety for props and events
|