├── .gitattributes ├── src ├── lib │ ├── noop.js │ ├── to-px.js │ ├── is-ssr.js │ ├── aspect-ratio-16-9.js │ ├── is-dev.js │ ├── is-editor.js │ ├── is-mac.js │ ├── debounce.js │ ├── eq.js │ ├── is-empty.js │ ├── pick-by.js │ ├── clipboard.js │ ├── screenshot-url.js │ ├── share-code.js │ ├── notification.js │ ├── compress-json.js │ └── local-storage.js ├── components │ ├── presets │ │ ├── scope.js │ │ ├── index.js │ │ ├── simple.js │ │ ├── microlink.js │ │ ├── bytesandhumans.js │ │ ├── article.js │ │ ├── rauchg.js │ │ ├── news.js │ │ ├── vercell.js │ │ ├── fauna.js │ │ └── thepracticaldev.js │ ├── if.js │ ├── icons │ │ ├── svg.js │ │ ├── info.js │ │ ├── theme.js │ │ ├── keyboard.js │ │ └── github.js │ ├── link.js │ ├── code.js │ ├── button.js │ ├── main.js │ ├── button-icon.js │ ├── choose.js │ ├── lazy-image.js │ ├── tabs.js │ ├── overlay.js │ ├── inline.macro.js │ ├── searchable-select.js │ ├── drag-bars.js │ ├── live-editor.js │ └── json-viewer.js ├── hooks │ ├── use-loading.js │ ├── use-key-bindings.js │ ├── use-query-state.js │ └── use-screenshot-url.js ├── pages │ ├── _document.js │ ├── _app.js │ └── index.js └── theme.js ├── .npmrc ├── README.md ├── .babelrc ├── jsconfig.json ├── next.config.js ├── .editorconfig ├── .gitignore ├── .travis.yml ├── LICENSE.md ├── package.json └── CHANGELOG.md /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /src/lib/noop.js: -------------------------------------------------------------------------------- 1 | export default () => {} 2 | -------------------------------------------------------------------------------- /src/lib/to-px.js: -------------------------------------------------------------------------------- 1 | export default n => `${n}px` 2 | -------------------------------------------------------------------------------- /src/lib/is-ssr.js: -------------------------------------------------------------------------------- 1 | export default typeof window === 'undefined' 2 | -------------------------------------------------------------------------------- /src/lib/aspect-ratio-16-9.js: -------------------------------------------------------------------------------- 1 | export default width => (width * 9) / 16 2 | -------------------------------------------------------------------------------- /src/lib/is-dev.js: -------------------------------------------------------------------------------- 1 | export default process.env.NODE_ENV === 'development' 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | unsafe-perm=true 2 | save-prefix=~ 3 | shrinkwrap=false 4 | save=false 5 | -------------------------------------------------------------------------------- /src/lib/is-editor.js: -------------------------------------------------------------------------------- 1 | export default Router => Router.asPath.startsWith('/editor') 2 | -------------------------------------------------------------------------------- /src/lib/is-mac.js: -------------------------------------------------------------------------------- 1 | import isSSR from './is-ssr' 2 | export default !isSSR && window.navigator.platform.match('Mac') 3 | -------------------------------------------------------------------------------- /src/lib/debounce.js: -------------------------------------------------------------------------------- 1 | import { debounce } from 'throttle-debounce' 2 | export default (fn, ms = 600) => debounce(ms, fn) 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | microlink cards 3 |
4 | -------------------------------------------------------------------------------- /src/lib/eq.js: -------------------------------------------------------------------------------- 1 | import stringify from 'fast-safe-stringify' 2 | export default (str1, str2) => stringify(str1) === stringify(str2) 3 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["next/babel"], 3 | "plugins": ["macros", ["babel-plugin-styled-components", { "ssr": true }]] 4 | } 5 | -------------------------------------------------------------------------------- /src/lib/is-empty.js: -------------------------------------------------------------------------------- 1 | export default obj => 2 | [Object, Array].includes((obj || {}).constructor) && 3 | !Object.entries(obj || {}).length 4 | -------------------------------------------------------------------------------- /src/lib/pick-by.js: -------------------------------------------------------------------------------- 1 | export default obj => { 2 | Object.keys(obj).forEach(key => obj[key] == null && delete obj[key]) 3 | return obj 4 | } 5 | -------------------------------------------------------------------------------- /src/components/presets/scope.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | import Link from '../link' 3 | 4 | export * from 'theme-ui' 5 | export { Link, styled } 6 | -------------------------------------------------------------------------------- /src/lib/clipboard.js: -------------------------------------------------------------------------------- 1 | export const read = async () => navigator.clipboard.readText() 2 | export const write = async text => navigator.clipboard.writeText(text) 3 | export default { read, write } 4 | -------------------------------------------------------------------------------- /src/lib/screenshot-url.js: -------------------------------------------------------------------------------- 1 | import { getApiUrl } from '@microlink/mql' 2 | 3 | export default (url, opts) => { 4 | const [screenshotUrl] = getApiUrl(url, opts) 5 | return screenshotUrl 6 | } 7 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "@/package.json": ["./package.json"], 6 | "@/*": ["./src/*"] 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | experimental: { 3 | jsconfigPaths: true 4 | }, 5 | exportTrailingSlash: true, 6 | exportPathMap: function () { 7 | return { 8 | '/': { page: '/' }, 9 | '/editor': { page: '/' } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/lib/share-code.js: -------------------------------------------------------------------------------- 1 | export default url => ` 2 | 3 | 4 | 5 | ` 6 | -------------------------------------------------------------------------------- /src/lib/notification.js: -------------------------------------------------------------------------------- 1 | import { createSnackbar } from '@snackbar/core' 2 | 3 | export default (text, props) => 4 | createSnackbar(text, { 5 | actions: [ 6 | { 7 | text: '×' 8 | } 9 | ], 10 | timeout: 2000, 11 | maxStack: 2, 12 | ...props 13 | }) 14 | -------------------------------------------------------------------------------- /src/lib/compress-json.js: -------------------------------------------------------------------------------- 1 | import Msgpack from 'msgpack5' 2 | import URLSafeBase64 from 'urlsafe-base64' 3 | 4 | const msgpack = new Msgpack() 5 | 6 | export const marshall = value => URLSafeBase64.encode(msgpack.encode(value)) 7 | 8 | export const unmarshall = value => msgpack.decode(URLSafeBase64.decode(value)) 9 | -------------------------------------------------------------------------------- /src/components/if.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types' 2 | 3 | const If = props => 4 | props.condition ? (props.render ? props.render() : props.children) : null 5 | 6 | If.propTypes = { 7 | condition: PropTypes.bool.isRequired, 8 | children: PropTypes.node, 9 | render: PropTypes.func 10 | } 11 | 12 | export default If 13 | -------------------------------------------------------------------------------- /src/lib/local-storage.js: -------------------------------------------------------------------------------- 1 | /* global localStorage */ 2 | 3 | import isSSR from './is-ssr' 4 | import noop from './noop' 5 | 6 | export const get = isSSR ? noop : window.localStorage.getItem.bind(localStorage) 7 | export const set = isSSR ? noop : window.localStorage.setItem.bind(localStorage) 8 | 9 | export default { get, set } 10 | -------------------------------------------------------------------------------- /src/components/icons/svg.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | 3 | const Svg = styled('svg')`` 4 | 5 | export default ({ color, size, ...props }) => ( 6 | 14 | ) 15 | -------------------------------------------------------------------------------- /src/components/link.js: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react' 2 | 3 | export default props => { 4 | useEffect(() => { 5 | const link = document.createElement('link') 6 | Object.keys(props).forEach(key => (link[key] = props[key])) 7 | document.head.appendChild(link) 8 | return () => document.head.removeChild(link) 9 | }, []) 10 | return false 11 | } 12 | -------------------------------------------------------------------------------- /src/components/code.js: -------------------------------------------------------------------------------- 1 | import { Box } from 'theme-ui' 2 | 3 | export default ({ sx, ...props }) => ( 4 | 18 | ) 19 | -------------------------------------------------------------------------------- /src/components/button.js: -------------------------------------------------------------------------------- 1 | import { Button } from 'theme-ui' 2 | 3 | export default ({ sx, ...props }) => ( 4 |