@startlibs/components 1.0.4 → 1.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/lib/BasicBulletList.mjs +9 -0
- package/lib/BasicBulletList.mjs.map +1 -0
- package/lib/Button.mjs +95 -0
- package/lib/Button.mjs.map +1 -0
- package/lib/ContextMenu.mjs +452 -0
- package/lib/ContextMenu.mjs.map +1 -0
- package/lib/Dialog.mjs +232 -0
- package/lib/Dialog.mjs.map +1 -0
- package/lib/Draggable.mjs +880 -0
- package/lib/Draggable.mjs.map +1 -0
- package/lib/ErrorBoundary.mjs +108 -0
- package/lib/ErrorBoundary.mjs.map +1 -0
- package/lib/FillLastLineResizer.mjs +238 -0
- package/lib/FillLastLineResizer.mjs.map +1 -0
- package/lib/Flip.mjs +604 -0
- package/lib/Flip.mjs.map +1 -0
- package/lib/FlipList.mjs +186 -0
- package/lib/FlipList.mjs.map +1 -0
- package/lib/FormatDate.mjs +25 -0
- package/lib/FormatDate.mjs.map +1 -0
- package/lib/Icon.mjs +50 -0
- package/lib/Icon.mjs.map +1 -0
- package/lib/Image.mjs +41 -0
- package/lib/Image.mjs.map +1 -0
- package/lib/Link.mjs +116 -0
- package/lib/Link.mjs.map +1 -0
- package/lib/Loading.mjs +10 -0
- package/lib/Loading.mjs.map +1 -0
- package/lib/LoadingDiv.mjs +83 -0
- package/lib/LoadingDiv.mjs.map +1 -0
- package/lib/Notifications.mjs +63 -0
- package/lib/Notifications.mjs.map +1 -0
- package/lib/PageLoader.mjs +42 -0
- package/lib/PageLoader.mjs.map +1 -0
- package/lib/PersistentNotifications.mjs +130 -0
- package/lib/PersistentNotifications.mjs.map +1 -0
- package/lib/Popup.mjs +49 -0
- package/lib/Popup.mjs.map +1 -0
- package/lib/SplitColumnsContainer.mjs +43 -0
- package/lib/SplitColumnsContainer.mjs.map +1 -0
- package/lib/SwitchDiv.mjs +61 -0
- package/lib/SwitchDiv.mjs.map +1 -0
- package/lib/TextButton.mjs +41 -0
- package/lib/TextButton.mjs.map +1 -0
- package/lib/ToastNotifications.mjs +215 -0
- package/lib/ToastNotifications.mjs.map +1 -0
- package/lib/Tooltip.mjs +160 -0
- package/lib/Tooltip.mjs.map +1 -0
- package/lib/TransitionDiv.mjs +56 -0
- package/lib/TransitionDiv.mjs.map +1 -0
- package/lib/WarningDialog.mjs +84 -0
- package/lib/WarningDialog.mjs.map +1 -0
- package/lib/alt/buttons/OnClickLoadingButton.mjs +36 -0
- package/lib/alt/buttons/OnClickLoadingButton.mjs.map +1 -0
- package/lib/alt/dialogs/DialogWithImageHeader.mjs +14 -0
- package/lib/alt/dialogs/DialogWithImageHeader.mjs.map +1 -0
- package/lib/alt/dialogs/DialogWithSidebar.mjs +106 -0
- package/lib/alt/dialogs/DialogWithSidebar.mjs.map +1 -0
- package/lib/alt/dialogs/MobileBubbleDialog.mjs +49 -0
- package/lib/alt/dialogs/MobileBubbleDialog.mjs.map +1 -0
- package/lib/containers/DialogContainer.mjs +413 -0
- package/lib/containers/DialogContainer.mjs.map +1 -0
- package/lib/containers/Reposition.mjs +35 -0
- package/lib/containers/Reposition.mjs.map +1 -0
- package/lib/containers/usePositioning.mjs +294 -0
- package/lib/containers/usePositioning.mjs.map +1 -0
- package/lib/index.cjs +5000 -0
- package/lib/index.cjs.map +1 -0
- package/lib/index.mjs +37 -0
- package/lib/index.mjs.map +1 -0
- package/lib/useDialogWithToggle.mjs +18 -0
- package/lib/useDialogWithToggle.mjs.map +1 -0
- package/lib/willUseIsSticky.mjs +123 -0
- package/lib/willUseIsSticky.mjs.map +1 -0
- package/package.json +44 -29
- package/src/BasicBulletList.jsx +21 -0
- package/src/Button.jsx +288 -0
- package/src/ContextMenu.jsx +621 -0
- package/src/Dialog.jsx +413 -0
- package/src/Draggable.jsx +801 -0
- package/src/ErrorBoundary.jsx +75 -0
- package/src/FillLastLineResizer.jsx +226 -0
- package/src/Flip.jsx +560 -0
- package/src/FlipList.jsx +136 -0
- package/src/FormatDate.jsx +9 -0
- package/src/Icon.jsx +49 -0
- package/src/Image.jsx +23 -0
- package/src/Link.jsx +68 -0
- package/src/Loading.jsx +29 -0
- package/src/LoadingDiv.jsx +75 -0
- package/src/Notifications.jsx +89 -0
- package/src/PageLoader.jsx +48 -0
- package/src/PersistentNotifications.jsx +182 -0
- package/src/Popup.jsx +49 -0
- package/src/SplitColumnsContainer.jsx +63 -0
- package/src/SwitchDiv.jsx +30 -0
- package/src/TextButton.jsx +34 -0
- package/src/ToastNotifications.jsx +298 -0
- package/src/Tooltip.jsx +158 -0
- package/src/TransitionDiv.jsx +34 -0
- package/src/WarningDialog.jsx +70 -0
- package/src/alt/buttons/OnClickLoadingButton.jsx +16 -0
- package/src/alt/dialogs/DialogWithImageHeader.jsx +42 -0
- package/src/alt/dialogs/DialogWithSidebar.jsx +135 -0
- package/src/alt/dialogs/MobileBubbleDialog.jsx +56 -0
- package/src/containers/DialogContainer.jsx +423 -0
- package/src/containers/Reposition.jsx +24 -0
- package/src/containers/usePositioning.jsx +305 -0
- package/src/index.js +35 -0
- package/src/useDialogWithToggle.jsx +12 -0
- package/src/willUseIsSticky.jsx +113 -0
- package/.babelrc +0 -27
- package/lib/index.js +0 -5429
- package/rollup.config.js +0 -52
- package/yarn-error.log +0 -3724
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import _ from 'lodash/fp'
|
|
3
|
+
import {useUpdateEffect} from '@startlibs/core'
|
|
4
|
+
import {postFetcher} from '@startlibs/utils'
|
|
5
|
+
import {useLocation} from './Link'
|
|
6
|
+
|
|
7
|
+
const ResetOnLocationChange = ({children,reset}) => {
|
|
8
|
+
const location = useLocation()
|
|
9
|
+
useUpdateEffect(() => {
|
|
10
|
+
reset()
|
|
11
|
+
}, [location]);
|
|
12
|
+
return children
|
|
13
|
+
}
|
|
14
|
+
export class ErrorBoundary extends React.Component {
|
|
15
|
+
constructor(props) {
|
|
16
|
+
super(props);
|
|
17
|
+
this.state = { hasError: false };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
componentDidUpdate(prevProps) {
|
|
21
|
+
if (this.props.location !== prevProps.location) {
|
|
22
|
+
this.setState({hasError:false})
|
|
23
|
+
}
|
|
24
|
+
if (this.props.resetOn !== prevProps.resetOn) {
|
|
25
|
+
this.setState({hasError:false})
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
componentDidCatch(e, info) {
|
|
30
|
+
if (_.get([0],e) === 'login' && _.get([1,'status'],e) === 401) {
|
|
31
|
+
window.location = "/login"
|
|
32
|
+
}
|
|
33
|
+
if (e?.notFound) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
var error = e && e.stack
|
|
37
|
+
try {
|
|
38
|
+
if (!e || !e.stack) {
|
|
39
|
+
error = JSON.stringify(e)
|
|
40
|
+
}
|
|
41
|
+
} catch (exception) {
|
|
42
|
+
error = e.toString()
|
|
43
|
+
}
|
|
44
|
+
if (!(/bot|spider|crawl/i.test(window.navigator.userAgent))) {
|
|
45
|
+
postFetcher("/log/errorBoundary", {
|
|
46
|
+
error,
|
|
47
|
+
message: e?.message,
|
|
48
|
+
name: e?.name,
|
|
49
|
+
componentStack: info?.componentStack,
|
|
50
|
+
url: window.location.href,
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static getDerivedStateFromError(error) {
|
|
56
|
+
// Update state so the next render will show the fallback UI.
|
|
57
|
+
return { hasError: true, error};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
render() {
|
|
61
|
+
const {Error,children,...props} = this.props
|
|
62
|
+
const {hasError,error} = this.state
|
|
63
|
+
const reset =() => this.setState({hasError:false,error:null})
|
|
64
|
+
if (hasError) {
|
|
65
|
+
if (React.isValidElement(Error)) {
|
|
66
|
+
return <ResetOnLocationChange reset={reset}>{Error}</ResetOnLocationChange>
|
|
67
|
+
}
|
|
68
|
+
// You can render any custom fallback UI
|
|
69
|
+
return <ResetOnLocationChange reset={reset}><Error {...props} error={error} fixed={reset}/></ResetOnLocationChange>;
|
|
70
|
+
}
|
|
71
|
+
return children;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// StartlibsProvider.registerInternal('ErrorBoundary',ErrorBoundary)
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import {isMobile} from '@startlibs/utils'
|
|
3
|
+
|
|
4
|
+
const isNodeJunction = (nextNode) => nextNode && !nextNode.hasChangedLine && nextNode.words[0]!==''
|
|
5
|
+
|
|
6
|
+
const calculateCanvasFillWidth = (nodes, maxWidth, ctx) => {
|
|
7
|
+
let lineCount = 0
|
|
8
|
+
let currentNodeLine = [];
|
|
9
|
+
let biggestWidth = 0
|
|
10
|
+
|
|
11
|
+
let previousWidth = 0;
|
|
12
|
+
let previousNodesLineWidth = 0
|
|
13
|
+
let currentMultiNodeWordWidth = 0
|
|
14
|
+
|
|
15
|
+
let lineWordsDebug = ''
|
|
16
|
+
|
|
17
|
+
nodes.forEach(({font,hasChangedLine,words}, nodeIndex) => {
|
|
18
|
+
ctx.font = font
|
|
19
|
+
const nextNode = nodes[nodeIndex+1]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
words.forEach((word,wordIndex) => {
|
|
23
|
+
const {width} = ctx.measureText(currentNodeLine.concat(word || (currentNodeLine.length ? '' : ' ')).join(' '));
|
|
24
|
+
const realizedWidth = width + previousNodesLineWidth
|
|
25
|
+
const overflowed = realizedWidth >= maxWidth
|
|
26
|
+
const lastWord = wordIndex === words.length - 1
|
|
27
|
+
if (!overflowed) {
|
|
28
|
+
if (lastWord && (nextNode && !nextNode.hasChangedLine)) {
|
|
29
|
+
previousNodesLineWidth = realizedWidth
|
|
30
|
+
currentNodeLine = []
|
|
31
|
+
if (word!=='' && isNodeJunction(nextNode)) {
|
|
32
|
+
currentMultiNodeWordWidth += ctx.measureText(word || ' ').width
|
|
33
|
+
}
|
|
34
|
+
} else {
|
|
35
|
+
currentNodeLine.push(word);
|
|
36
|
+
currentMultiNodeWordWidth = 0;
|
|
37
|
+
biggestWidth = biggestWidth > realizedWidth ? biggestWidth : realizedWidth
|
|
38
|
+
}
|
|
39
|
+
lineWordsDebug += ' ' + word
|
|
40
|
+
previousWidth = realizedWidth;
|
|
41
|
+
} else {
|
|
42
|
+
lineCount++;
|
|
43
|
+
lineWordsDebug = ''
|
|
44
|
+
if (lastWord) {
|
|
45
|
+
currentMultiNodeWordWidth += ctx.measureText(word || ' ').width;
|
|
46
|
+
previousNodesLineWidth = currentMultiNodeWordWidth;
|
|
47
|
+
currentNodeLine = []
|
|
48
|
+
} else {
|
|
49
|
+
previousNodesLineWidth = currentMultiNodeWordWidth;
|
|
50
|
+
currentMultiNodeWordWidth = 0;
|
|
51
|
+
currentNodeLine = [word]
|
|
52
|
+
}
|
|
53
|
+
previousWidth = 0
|
|
54
|
+
}
|
|
55
|
+
if (lastWord && (!nextNode || nextNode?.hasChangedLine)) {
|
|
56
|
+
lineCount++;
|
|
57
|
+
currentMultiNodeWordWidth =0;
|
|
58
|
+
currentNodeLine = [];
|
|
59
|
+
previousWidth = 0;
|
|
60
|
+
previousNodesLineWidth=0;
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
});
|
|
64
|
+
return {max: biggestWidth, lines:lineCount}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const getCanvasFillWidth = (nodes, maxWidth, ctx, maxLines) => {
|
|
68
|
+
const {max, lines} = calculateCanvasFillWidth(nodes, maxWidth-1, ctx)
|
|
69
|
+
if (lines > maxLines) {
|
|
70
|
+
return null
|
|
71
|
+
} else {
|
|
72
|
+
const smallerResult = getCanvasFillWidth(nodes, max-1, ctx, lines)
|
|
73
|
+
if (smallerResult === null || max === smallerResult) {
|
|
74
|
+
return maxLines === undefined ? maxWidth : Math.ceil(max)
|
|
75
|
+
} else {
|
|
76
|
+
return smallerResult
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export class FillLastLineResizer extends React.Component {
|
|
82
|
+
static defaultProps = {
|
|
83
|
+
Tag: 'div'
|
|
84
|
+
}
|
|
85
|
+
fontIsLoaded = false
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
setRef = (el) => {
|
|
89
|
+
this.el = el
|
|
90
|
+
if (el && parseInt(this.el.style.maxWidth, 10) !== parseInt(this.lastMaxWidth, 10)) {
|
|
91
|
+
this.resizeEvent()
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
resizeEvent = (fontLoadedOrEvent) => {
|
|
96
|
+
const fromDialog = typeof fontLoadedOrEvent === 'object' ? fontLoadedOrEvent.detail && fontLoadedOrEvent.detail.dialog : false
|
|
97
|
+
if (fromDialog) return;
|
|
98
|
+
const fontAlreadyLoaded = window.getComputedStyle(this.el).fontWeight === '500' && window.getComputedStyle(this.el).fontFamily.indexOf('Roboto') > 0
|
|
99
|
+
if (fontAlreadyLoaded) {
|
|
100
|
+
this.el.style.fontFamily = 'Roboto, sans-serif'
|
|
101
|
+
this.fontIsLoaded = true
|
|
102
|
+
}
|
|
103
|
+
if (this.fontIsLoaded || this.props.resizeOnMount || fontLoadedOrEvent === true || document.readyState === 'complete') {
|
|
104
|
+
this.fontIsLoaded = true
|
|
105
|
+
} else {
|
|
106
|
+
return
|
|
107
|
+
}
|
|
108
|
+
this.el.style.removeProperty('max-width')
|
|
109
|
+
if (this.props.shouldCancelResize === true || (typeof this.props.shouldCancelResize === 'function' && this.props.shouldCancelResize())) {
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (isMobile() && this.el.firstElementChild) {
|
|
114
|
+
return
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const {offsetWidth, offsetHeight} = this.el
|
|
118
|
+
if (offsetWidth && offsetHeight) {
|
|
119
|
+
const range = document.createRange()
|
|
120
|
+
range.setStart(this.el, 0)
|
|
121
|
+
range.setEnd(this.el, this.el.childNodes.length)
|
|
122
|
+
if (range.getClientRects().length <= 1) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
let newMaxWidth = 0;
|
|
126
|
+
if (this.props.withoutCanvas) {
|
|
127
|
+
newMaxWidth = this.getMaxWidth(this.el, offsetHeight, offsetWidth, 256, offsetWidth)
|
|
128
|
+
} else {
|
|
129
|
+
try {
|
|
130
|
+
const canvasCtx = document.createElement("canvas").getContext("2d");
|
|
131
|
+
const nodeIterator = document.createNodeIterator(this.el, NodeFilter.SHOW_TEXT)
|
|
132
|
+
const text = this.el.innerText
|
|
133
|
+
let lastIndex = -1
|
|
134
|
+
let node;
|
|
135
|
+
const nodes = []
|
|
136
|
+
while (node = nodeIterator.nextNode()) {
|
|
137
|
+
const currentText = node.textContent.replace( / +/g, ' ' )
|
|
138
|
+
const currentIndex = text.indexOf(currentText,lastIndex+1)
|
|
139
|
+
nodes.push({
|
|
140
|
+
font:window.getComputedStyle(node.parentElement).font,
|
|
141
|
+
hasChangedLine:text[currentIndex-1]==='\n',
|
|
142
|
+
words:currentText.split(' ')
|
|
143
|
+
})
|
|
144
|
+
lastIndex = currentIndex
|
|
145
|
+
}
|
|
146
|
+
newMaxWidth = getCanvasFillWidth(nodes, offsetWidth, canvasCtx)
|
|
147
|
+
} catch (e) {
|
|
148
|
+
console.log(e)
|
|
149
|
+
newMaxWidth = offsetWidth
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
this.el.style.maxWidth = newMaxWidth + 'px'
|
|
154
|
+
const {offsetHeight: newOffsetHeight} = this.el
|
|
155
|
+
|
|
156
|
+
// confere se o maxWidth antigo ainda serve, garantir que não haja influencia de um ou outro pixel
|
|
157
|
+
if (this.lastMaxWidth) {
|
|
158
|
+
this.el.style.maxWidth = this.lastMaxWidth + 'px'
|
|
159
|
+
const {offsetHeight: lastOffsetHeight} = this.el
|
|
160
|
+
if (newOffsetHeight !== lastOffsetHeight || this.lastMaxWidth >= this.el.offsetWidth) {
|
|
161
|
+
// if (this.el.tagName.toLowerCase()==='ul') {
|
|
162
|
+
// console.log(newMaxWidth)
|
|
163
|
+
// }
|
|
164
|
+
this.lastMaxWidth = newMaxWidth
|
|
165
|
+
this.el.style.maxWidth = this.lastMaxWidth + 'px'
|
|
166
|
+
}
|
|
167
|
+
} else {
|
|
168
|
+
this.lastMaxWidth = newMaxWidth
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
getMaxWidth = (element, prevHeight, prevWidth, window, originalWidth) => {
|
|
174
|
+
const newWidth = Math.max(1, prevWidth - window)
|
|
175
|
+
element.style.maxWidth = newWidth + 'px'
|
|
176
|
+
if (element.offsetHeight === prevHeight && prevWidth > 10) {
|
|
177
|
+
return this.getMaxWidth(element, prevHeight, newWidth, window, originalWidth)
|
|
178
|
+
} else if (window > 1) {
|
|
179
|
+
return this.getMaxWidth(element, prevHeight, prevWidth, window / 2, originalWidth)
|
|
180
|
+
} else if (prevWidth < 10) {
|
|
181
|
+
return originalWidth > prevWidth ? originalWidth : 10
|
|
182
|
+
} else {
|
|
183
|
+
return prevWidth + 1
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
componentDidMount() {
|
|
188
|
+
window.addEventListener('stepResize', this.resizeEvent)
|
|
189
|
+
if (document.readyState === 'complete') {
|
|
190
|
+
this.resizeEvent()
|
|
191
|
+
} else {
|
|
192
|
+
window.addEventListener('load', this.resizeEvent)
|
|
193
|
+
if (window.document.fonts && window.document.fonts.ready && window.document.fonts.ready.catch) {
|
|
194
|
+
window.document.fonts.ready.catch(_ => _).then(() => {
|
|
195
|
+
window.removeEventListener('load', this.resizeEvent)
|
|
196
|
+
this.resizeEvent(true)
|
|
197
|
+
})
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
componentWillUnmount() {
|
|
203
|
+
window.removeEventListener('stepResize', this.resizeEvent)
|
|
204
|
+
window.removeEventListener('load', this.resizeEvent)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
componentDidUpdate() {
|
|
208
|
+
this.resizeEvent()
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
shouldComponentUpdate(nextProps) {
|
|
212
|
+
const ignoreHtml = nextProps.dangerouslySetInnerHTML && this.props.dangerouslySetInnerHTML &&
|
|
213
|
+
nextProps.dangerouslySetInnerHTML.__html === this.props.dangerouslySetInnerHTML.__html
|
|
214
|
+
const isShallowEqual = Object.keys(nextProps).every(key => this.props[key] === nextProps[key] || (ignoreHtml && key === "dangerouslySetInnerHTML"))
|
|
215
|
+
return !isShallowEqual;
|
|
216
|
+
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
render() {
|
|
220
|
+
const {Tag, linkColor, resizeOnMount, shouldCancelResize, ...rest} = this.props
|
|
221
|
+
return <Tag ref={this.setRef} {...rest}/>
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
FillLastLineResizer.ul = (props) => <FillLastLineResizer Tag='ul' {...props}/>
|
|
226
|
+
FillLastLineResizer.h2 = (props) => <FillLastLineResizer Tag='h2' {...props}/>
|