├── .gitattributes
├── .github
└── workflows
│ └── node.js.yml
├── .gitignore
├── .npmignore
├── .prettierrc.js
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── docs.sh
├── docs
├── .gitignore
├── README.md
├── appveyor.yml
├── bundle.css
├── cypress.json
├── cypress
│ ├── fixtures
│ │ └── example.json
│ ├── integration
│ │ └── spec.js
│ ├── plugins
│ │ └── index.js
│ └── support
│ │ ├── commands.js
│ │ └── index.js
├── jsdoc
│ ├── conf.js
│ ├── plugins
│ │ └── svelte.js
│ └── template
│ │ └── publish.js
├── package-lock.json
├── package.json
├── rollup.config.js
├── src
│ ├── client.js
│ ├── components
│ │ ├── Code.svelte
│ │ ├── CodepenButton.svelte
│ │ ├── DocHeader.svelte
│ │ ├── Example.svelte
│ │ ├── JSDoc.svelte
│ │ ├── Nav.svelte
│ │ └── Sidebar.svelte
│ ├── routes
│ │ ├── _error.svelte
│ │ ├── _layout.svelte
│ │ ├── about.svelte
│ │ ├── blog
│ │ │ ├── [slug].json.js
│ │ │ ├── [slug].svelte
│ │ │ ├── _posts.js
│ │ │ ├── index.json.js
│ │ │ └── index.svelte
│ │ ├── bulma
│ │ │ ├── hero.svelte
│ │ │ ├── intro.svelte
│ │ │ ├── media.svelte
│ │ │ ├── table.svelte
│ │ │ └── tiles.svelte
│ │ ├── components
│ │ │ ├── [slug].json.js
│ │ │ ├── button.svelte
│ │ │ ├── collapse.svelte
│ │ │ ├── dialog.svelte
│ │ │ ├── field.svelte
│ │ │ ├── icon.svelte
│ │ │ ├── input.svelte
│ │ │ ├── jsdocs.json
│ │ │ ├── message.svelte
│ │ │ ├── modal.svelte
│ │ │ ├── modalcard.svelte
│ │ │ ├── notification.svelte
│ │ │ ├── progress.svelte
│ │ │ ├── select.svelte
│ │ │ ├── snackbar.svelte
│ │ │ ├── switch.svelte
│ │ │ ├── tabs.svelte
│ │ │ ├── tag.svelte
│ │ │ ├── toast.svelte
│ │ │ └── tooltip.svelte
│ │ ├── index.svelte
│ │ └── install
│ │ │ └── index.svelte
│ ├── server.js
│ ├── service-worker.js
│ └── template.html
└── static
│ ├── favicon.ico
│ ├── favicon.png
│ ├── global.css
│ ├── great-success.png
│ ├── logo-192.png
│ ├── logo-512.png
│ ├── manifest.json
│ ├── svelma-logo-ico.png
│ ├── svelma-logo.png
│ └── svelma-logo.svg
├── package-lock.json
├── package.json
├── public
├── favicon.png
├── global.css
└── index.html
├── rollup.config.js
└── src
├── components
├── Button.svelte
├── Collapse.svelte
├── Dialog
│ ├── Dialog.svelte
│ └── index.js
├── Dropdown.svelte
├── Field.svelte
├── File.svelte
├── Icon.svelte
├── Input.svelte
├── Message.svelte
├── Modal
│ ├── Modal.svelte
│ ├── ModalCard.svelte
│ └── index.js
├── Notice.svelte
├── Notices.svelte
├── Notification
│ ├── Notification.svelte
│ ├── NotificationNotice.svelte
│ └── index.js
├── Progress.svelte
├── Select.svelte
├── Snackbar
│ ├── Snackbar.svelte
│ └── index.js
├── Switch.svelte
├── Tabs
│ ├── Tab.svelte
│ ├── Tabs.svelte
│ ├── index.js
│ └── riskview_example.json
├── Tag
│ ├── Tag.svelte
│ ├── Taglist.svelte
│ └── index.js
├── Toast
│ ├── Toast.svelte
│ └── index.js
└── Tooltip.svelte
├── index.js
└── utils
└── index.js
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.svelte linguist-language=HTML
--------------------------------------------------------------------------------
/.github/workflows/node.js.yml:
--------------------------------------------------------------------------------
1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3 |
4 | name: Node.js CI
5 |
6 | on:
7 | push:
8 | branches: [ master ]
9 | pull_request:
10 | branches: [ master ]
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | strategy:
18 | matrix:
19 | node-version: [10.x, 12.x, 14.x, 16.x]
20 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
21 |
22 | steps:
23 | - uses: actions/checkout@v2
24 | - name: Use Node.js ${{ matrix.node-version }}
25 | uses: actions/setup-node@v2
26 | with:
27 | node-version: ${{ matrix.node-version }}
28 | - run: npm ci
29 | - run: npm run build --if-present
30 | - run: npm run test --if-present
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | dist/*
4 | public/build
5 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/c0bra/svelma/ddd412e79085f47646b3739f5d05277219f070a2/.npmignore
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | trailingComma: 'es5',
3 | tabWidth: 2,
4 | semi: false,
5 | singleQuote: true,
6 | printWidth: 120,
7 | semi: false,
8 | }
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js: lts/*
3 |
4 | branches:
5 | only:
6 | - master
7 | - dev
8 | # Tags
9 | - /^v\d+\.\d+(\.\d+)?(-\S*)?$/
10 | - /^greenkeeper\//
11 |
12 | addons:
13 | apt:
14 | packages:
15 | - xvfb
16 |
17 | install:
18 | - export DISPLAY=':99.0'
19 | - Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
20 | - npm ci || npm install
21 |
22 | script: skip
23 |
24 | jobs:
25 | include:
26 | - stage: release
27 | node_js: lts/*
28 | deploy:
29 | provider: script
30 | skip_cleanup: true
31 | script:
32 | - npx semantic-release
33 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 0.4.5
2 | Allow binding activeTab property in Tabs #104
3 |
4 | ## 0.4.4
5 | https://github.com/c0bra/svelma/pull/96
6 | https://github.com/c0bra/svelma/pull/91
7 |
8 | ## 0.4.3
9 | ported from abbychau/svelma2
10 |
11 | ## 0.4.2 (2021-03-18)
12 | * Add Modal Card Component
13 | * Use Modal is-active native class(remove buggy is-active binding)
14 |
15 | ## 0.4.1 (2021-03-17)
16 |
17 | * Upgrade Bulma to 0.9.2
18 | * Fix Modal's bug for unable to reopen
19 | * Upgrade all dependencies including main and docs
20 | * Fix all runtime build warnings
21 |
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Brian Hann, 2021 Abby Chau
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Svelma
2 |
3 | > Svelma is a set of UI components for [Svelte](https://svelte.dev) based on the [Bulma](http://bulma.io) CSS framework.
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | [Change Log](CHANGELOG.md)
12 |
13 |
14 |
15 | # Documentation
16 |
17 | [See docs + demos site here](https://docs-abbychau.vercel.app/svelma)
18 |
19 | # Quick Start
20 |
21 | ### 1. Import svelma and dependencies via npm to your project
22 |
23 | ```bash
24 | $ npm install --save bulma svelma
25 | $ npm install node-sass svelte-preprocess rollup-plugin-postcss --save-dev
26 | ```
27 |
28 | ### 2. Add the postcss plugin to your rollup config
29 |
30 | ```js
31 | // rollup.config.js
32 | import postcss from 'rollup-plugin-postcss'
33 | import preprocess from 'svelte-preprocess'
34 |
35 | // ...
36 |
37 | export default {
38 | // ...
39 | plugins: [
40 | svelte({
41 | // ...
42 | preprocess: preprocess()
43 | }),
44 |
45 | postcss(),
46 | ]
47 | }
48 | ```
49 |
50 | ### 3. Import Bulma's CSS and Svelma components
51 |
52 | ```html
53 |
54 |
58 |
59 | I'm a Button!
60 | ```
61 |
62 | ### 4. Include [Font Awesome](https://fontawesome.com/) icons
63 |
64 | From CDN in your HTML page:
65 |
66 | ```html
67 |
68 | ```
69 |
70 | Or as an npm package imported into your root component:
71 |
72 | `$ npm install --save @fortawesome/fontawesome-free`
73 |
74 | ```html
75 |
76 |
80 | ```
81 |
82 | ### SSR
83 |
84 | If you are doing server-side rendering with Sapper (or [SvelteKit](https://kit.svelte.dev/)), you'll need to import the .svelte files directly so that your app can compile them, rather than importing from the compiled module.
85 |
86 | i.e.:
87 |
88 | ```js
89 | import Button from 'svelma/src/components/Button.svelte'
90 | ```
91 |
92 | instead of
93 |
94 | ```js
95 | import { Button } from 'svelma'
96 | ```
97 |
98 |
99 | # Inspiration
100 |
101 | Much thanks to the [Buefy](https://buefy.org) and [Svelma2](https://github.com/abbychau/svelma2) projects! It provided the inspiration and lots of code examples for this version of Svelma.
102 |
--------------------------------------------------------------------------------
/docs.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # abort on errors
4 | set -e
5 |
6 | NODE_ENV=production npm run build
7 | # NODE_ENV=production npm run jsdocs
8 | NODE_ENV=production npm run docs
9 |
10 | # navigate into the build output directory
11 | cd docs/__sapper__/export/svelma
12 |
13 | # if you are deploying to a custom domain
14 | # echo 'www.example.com' > CNAME
15 |
16 | git init
17 | git add -A
18 | git commit -m 'deploy'
19 |
20 | git push -f https://${GITHUB_TOKEN_SVELMA}@github.com/c0bra/svelma.git master:gh-pages
21 |
22 | cd -
--------------------------------------------------------------------------------
/docs/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | yarn-error.log
4 | /cypress/screenshots/
5 | /__sapper__/
6 |
7 | .vercel
8 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # sapper-template
2 |
3 | The default [Sapper](https://github.com/sveltejs/sapper) template, with branches for Rollup and webpack. To clone it and get started:
4 |
5 | ```bash
6 | # for Rollup
7 | npx degit sveltejs/sapper-template#rollup my-app
8 | # for webpack
9 | npx degit sveltejs/sapper-template#webpack my-app
10 | cd my-app
11 | npm install # or yarn!
12 | npm run dev
13 | ```
14 |
15 | Open up [localhost:3000](http://localhost:3000) and start clicking around.
16 |
17 | Consult [sapper.svelte.dev](https://sapper.svelte.dev) for help getting started.
18 |
19 |
20 | ## Structure
21 |
22 | Sapper expects to find two directories in the root of your project — `src` and `static`.
23 |
24 |
25 | ### src
26 |
27 | The [src](src) directory contains the entry points for your app — `client.js`, `server.js` and (optionally) a `service-worker.js` — along with a `template.html` file and a `routes` directory.
28 |
29 |
30 | #### src/routes
31 |
32 | This is the heart of your Sapper app. There are two kinds of routes — *pages*, and *server routes*.
33 |
34 | **Pages** are Svelte components written in `.svelte` files. When a user first visits the application, they will be served a server-rendered version of the route in question, plus some JavaScript that 'hydrates' the page and initialises a client-side router. From that point forward, navigating to other pages is handled entirely on the client for a fast, app-like feel. (Sapper will preload and cache the code for these subsequent pages, so that navigation is instantaneous.)
35 |
36 | **Server routes** are modules written in `.js` files, that export functions corresponding to HTTP methods. Each function receives Express `request` and `response` objects as arguments, plus a `next` function. This is useful for creating a JSON API, for example.
37 |
38 | There are three simple rules for naming the files that define your routes:
39 |
40 | * A file called `src/routes/about.svelte` corresponds to the `/about` route. A file called `src/routes/blog/[slug].svelte` corresponds to the `/blog/:slug` route, in which case `params.slug` is available to the route
41 | * The file `src/routes/index.svelte` (or `src/routes/index.js`) corresponds to the root of your app. `src/routes/about/index.svelte` is treated the same as `src/routes/about.svelte`.
42 | * Files and directories with a leading underscore do *not* create routes. This allows you to colocate helper modules and components with the routes that depend on them — for example you could have a file called `src/routes/_helpers/datetime.js` and it would *not* create a `/_helpers/datetime` route
43 |
44 |
45 | ### static
46 |
47 | The [static](static) directory contains any static assets that should be available. These are served using [sirv](https://github.com/lukeed/sirv).
48 |
49 | In your [service-worker.js](app/service-worker.js) file, you can import these as `files` from the generated manifest...
50 |
51 | ```js
52 | import { files } from '@sapper/service-worker';
53 | ```
54 |
55 | ...so that you can cache them (though you can choose not to, for example if you don't want to cache very large files).
56 |
57 |
58 | ## Bundler config
59 |
60 | Sapper uses Rollup or webpack to provide code-splitting and dynamic imports, as well as compiling your Svelte components. With webpack, it also provides hot module reloading. As long as you don't do anything daft, you can edit the configuration files to add whatever plugins you'd like.
61 |
62 |
63 | ## Production mode and deployment
64 |
65 | To start a production version of your app, run `npm run build && npm start`. This will disable live reloading, and activate the appropriate bundler plugins.
66 |
67 | You can deploy your application to any environment that supports Node 8 or above. As an example, to deploy to [Now](https://zeit.co/now), run these commands:
68 |
69 | ```bash
70 | npm install -g now
71 | now
72 | ```
73 |
74 |
75 | ## Using external components with webpack
76 |
77 | When using Svelte components installed from npm, such as [@sveltejs/svelte-virtual-list](https://github.com/sveltejs/svelte-virtual-list), Svelte needs the original component source (rather than any precompiled JavaScript that ships with the component). This allows the component to be rendered server-side, and also keeps your client-side app smaller.
78 |
79 | Because of that, it's essential that webpack doesn't treat the package as an *external dependency*. You can either modify the `externals` option under `server` in [webpack.config.js](webpack.config.js), or simply install the package to `devDependencies` rather than `dependencies`, which will cause it to get bundled (and therefore compiled) with your app:
80 |
81 | ```bash
82 | npm install -D @sveltejs/svelte-virtual-list
83 | ```
84 |
85 |
86 | ## Bugs and feedback
87 |
88 | Sapper is in early development, and may have the odd rough edge here and there. Please be vocal over on the [Sapper issue tracker](https://github.com/sveltejs/sapper/issues).
89 |
--------------------------------------------------------------------------------
/docs/appveyor.yml:
--------------------------------------------------------------------------------
1 | version: "{build}"
2 |
3 | shallow_clone: true
4 |
5 | init:
6 | - git config --global core.autocrlf false
7 |
8 | build: off
9 |
10 | environment:
11 | matrix:
12 | # node.js
13 | - nodejs_version: stable
14 |
15 | install:
16 | - ps: Install-Product node $env:nodejs_version
17 | - npm install cypress
18 | - npm install
19 |
--------------------------------------------------------------------------------
/docs/cypress.json:
--------------------------------------------------------------------------------
1 | {
2 | "baseUrl": "http://localhost:3000",
3 | "video": false
4 | }
--------------------------------------------------------------------------------
/docs/cypress/fixtures/example.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Using fixtures to represent data",
3 | "email": "hello@cypress.io",
4 | "body": "Fixtures are a great way to mock data for responses to routes"
5 | }
--------------------------------------------------------------------------------
/docs/cypress/integration/spec.js:
--------------------------------------------------------------------------------
1 | describe('Sapper template app', () => {
2 | beforeEach(() => {
3 | cy.visit('/')
4 | });
5 |
6 | it('has the correct
', () => {
7 | cy.contains('h1', 'Great success!')
8 | });
9 |
10 | it('navigates to /about', () => {
11 | cy.get('nav a').contains('about').click();
12 | cy.url().should('include', '/about');
13 | });
14 |
15 | it('navigates to /blog', () => {
16 | cy.get('nav a').contains('blog').click();
17 | cy.url().should('include', '/blog');
18 | });
19 | });
--------------------------------------------------------------------------------
/docs/cypress/plugins/index.js:
--------------------------------------------------------------------------------
1 | // ***********************************************************
2 | // This example plugins/index.js can be used to load plugins
3 | //
4 | // You can change the location of this file or turn off loading
5 | // the plugins file with the 'pluginsFile' configuration option.
6 | //
7 | // You can read more here:
8 | // https://on.cypress.io/plugins-guide
9 | // ***********************************************************
10 |
11 | // This function is called when a project is opened or re-opened (e.g. due to
12 | // the project's config changing)
13 |
14 | module.exports = (on, config) => {
15 | // `on` is used to hook into various events Cypress emits
16 | // `config` is the resolved Cypress config
17 | }
18 |
--------------------------------------------------------------------------------
/docs/cypress/support/commands.js:
--------------------------------------------------------------------------------
1 | // ***********************************************
2 | // This example commands.js shows you how to
3 | // create various custom commands and overwrite
4 | // existing commands.
5 | //
6 | // For more comprehensive examples of custom
7 | // commands please read more here:
8 | // https://on.cypress.io/custom-commands
9 | // ***********************************************
10 | //
11 | //
12 | // -- This is a parent command --
13 | // Cypress.Commands.add("login", (email, password) => { ... })
14 | //
15 | //
16 | // -- This is a child command --
17 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
18 | //
19 | //
20 | // -- This is a dual command --
21 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
22 | //
23 | //
24 | // -- This is will overwrite an existing command --
25 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
26 |
--------------------------------------------------------------------------------
/docs/cypress/support/index.js:
--------------------------------------------------------------------------------
1 | // ***********************************************************
2 | // This example support/index.js is processed and
3 | // loaded automatically before your test files.
4 | //
5 | // This is a great place to put global configuration and
6 | // behavior that modifies Cypress.
7 | //
8 | // You can change the location of this file or turn off
9 | // automatically serving support files with the
10 | // 'supportFile' configuration option.
11 | //
12 | // You can read more here:
13 | // https://on.cypress.io/configuration
14 | // ***********************************************************
15 |
16 | // Import commands.js using ES2015 syntax:
17 | import './commands'
18 |
19 | // Alternatively you can use CommonJS syntax:
20 | // require('./commands')
21 |
--------------------------------------------------------------------------------
/docs/jsdoc/conf.js:
--------------------------------------------------------------------------------
1 | const { resolve } = require('path')
2 |
3 | const root = resolve(__dirname, '../..')
4 |
5 | module.exports = {
6 | opts: {
7 | recurse: true,
8 | template: './template',
9 | destination: resolve(root, 'docs/src/routes/components/jsdocs.json'),
10 | },
11 | source: {
12 | include: [resolve(root, 'src/components')],
13 | includePattern: '.+\\.svelte$', // (js(doc|x)?
14 | },
15 | plugins: ['plugins/svelte.js'],
16 | }
17 |
--------------------------------------------------------------------------------
/docs/jsdoc/plugins/svelte.js:
--------------------------------------------------------------------------------
1 | // JSDoc plugin for Svelte
2 | const { basename, join, relative,resolve } = require('path')
3 | const svelte = require('svelte/compiler')
4 |
5 | const scriptLines = {}
6 |
7 | function seekScriptLine(source, filename) {
8 | // eslint-disable-next-line no-restricted-syntax
9 | for (const [i, line] of source.split(/\r?\n/).entries()) {
10 | if (line.trim() === '') {
11 | continue;
12 | }
13 |
14 | if (/
57 |
58 |
91 |
92 |
93 |
94 | {#if showCopy}
95 |
96 | Copy
97 |
98 | {/if}
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | {@html compiled}
107 |
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/docs/src/components/CodepenButton.svelte:
--------------------------------------------------------------------------------
1 |
100 |
101 |
107 |
108 |
114 |
--------------------------------------------------------------------------------
/docs/src/components/DocHeader.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
19 |
--------------------------------------------------------------------------------
/docs/src/components/Example.svelte:
--------------------------------------------------------------------------------
1 |
22 |
23 |
173 |
174 |
175 |
176 |
177 | Codesandbox
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
193 |
194 |
195 |
--------------------------------------------------------------------------------
/docs/src/components/JSDoc.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
13 |
14 | {#if jsdoc}
15 | {#if showHeader} {/if}
16 |
17 |
18 | {#if showHeader}API {/if}
19 |
20 |
21 |
22 |
23 |
24 | Name
25 | Description
26 | Type
27 | Values
28 | Default
29 |
30 |
31 |
32 | {#each jsdoc as doc}
33 |
34 |
35 | {doc.name}
36 |
37 |
38 | {@html doc.description}{#if doc.optional}, optional{/if}
39 |
40 | {(doc.type || []).join(', ')}
41 |
42 | {@html doc.values || '—'}
43 |
44 |
45 | {@html ('defaultvalue' in doc && `${doc.defaultvalue}
`) || '—'}
46 |
47 |
48 | {/each}
49 |
50 |
51 |
52 |
53 | {/if}
54 |
--------------------------------------------------------------------------------
/docs/src/components/Nav.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
19 |
20 | {#if false}
21 |
22 |
23 |
24 | home
25 |
26 |
27 | about
28 |
29 |
30 |
32 |
33 | blog
34 |
35 |
36 |
37 | {/if}
38 |
39 |
40 |
62 |
63 |
--------------------------------------------------------------------------------
/docs/src/components/Sidebar.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
18 |
19 |
68 |
69 |
70 |
112 |
--------------------------------------------------------------------------------
/docs/src/routes/_error.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
29 |
30 |
31 | {status}
32 |
33 |
34 | {status}
35 |
36 | {error.message}
37 |
38 | {#if dev && error.stack}
39 | {error.stack}
40 | {/if}
41 |
--------------------------------------------------------------------------------
/docs/src/routes/_layout.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
31 |
32 |
58 |
59 |
60 | Svelma
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/docs/src/routes/about.svelte:
--------------------------------------------------------------------------------
1 |
2 | About
3 |
4 |
5 | About this site
6 |
7 | This is the 'about' page. There's not much here.
--------------------------------------------------------------------------------
/docs/src/routes/blog/[slug].json.js:
--------------------------------------------------------------------------------
1 | import posts from './_posts.js';
2 |
3 | const lookup = new Map();
4 | posts.forEach(post => {
5 | lookup.set(post.slug, JSON.stringify(post));
6 | });
7 |
8 | export function get(req, res, next) {
9 | // the `slug` parameter is available because
10 | // this file is called [slug].json.js
11 | const { slug } = req.params;
12 |
13 | if (lookup.has(slug)) {
14 | res.writeHead(200, {
15 | 'Content-Type': 'application/json'
16 | });
17 |
18 | res.end(lookup.get(slug));
19 | } else {
20 | res.writeHead(404, {
21 | 'Content-Type': 'application/json'
22 | });
23 |
24 | res.end(JSON.stringify({
25 | message: `Not found`
26 | }));
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/docs/src/routes/blog/[slug].svelte:
--------------------------------------------------------------------------------
1 |
15 |
16 |
19 |
20 |
55 |
56 |
57 | {post.title}
58 |
59 |
60 | {post.title}
61 |
62 |
63 | {@html post.html}
64 |
--------------------------------------------------------------------------------
/docs/src/routes/blog/_posts.js:
--------------------------------------------------------------------------------
1 | // Ordinarily, you'd generate this data from markdown files in your
2 | // repo, or fetch them from a database of some kind. But in order to
3 | // avoid unnecessary dependencies in the starter template, and in the
4 | // service of obviousness, we're just going to leave it here.
5 |
6 | // This file is called `_posts.js` rather than `posts.js`, because
7 | // we don't want to create an `/blog/posts` route — the leading
8 | // underscore tells Sapper not to do that.
9 |
10 | const posts = [
11 | {
12 | title: 'What is Sapper?',
13 | slug: 'what-is-sapper',
14 | html: `
15 | First, you have to know what Svelte is. Svelte is a UI framework with a bold new idea: rather than providing a library that you write code with (like React or Vue, for example), it's a compiler that turns your components into highly optimized vanilla JavaScript. If you haven't already read the introductory blog post , you should!
16 |
17 | Sapper is a Next.js-style framework (more on that here ) built around Svelte. It makes it embarrassingly easy to create extremely high performance web apps. Out of the box, you get:
18 |
19 |
20 | Code-splitting, dynamic imports and hot module replacement, powered by webpack
21 | Server-side rendering (SSR) with client-side hydration
22 | Service worker for offline support, and all the PWA bells and whistles
23 | The nicest development experience you've ever had, or your money back
24 |
25 |
26 | It's implemented as Express middleware. Everything is set up and waiting for you to get started, but you keep complete control over the server, service worker, webpack config and everything else, so it's as flexible as you need it to be.
27 | `
28 | },
29 |
30 | {
31 | title: 'How to use Sapper',
32 | slug: 'how-to-use-sapper',
33 | html: `
34 | Step one
35 | Create a new project, using degit :
36 |
37 | npx degit sveltejs/sapper-template#rollup my-app
38 | cd my-app
39 | npm install # or yarn!
40 | npm run dev
41 |
42 |
43 | Step two
44 | Go to localhost:3000 . Open my-app
in your editor. Edit the files in the src/routes
directory or add new ones.
45 |
46 | Step three
47 | ...
48 |
49 | Step four
50 | Resist overdone joke formats.
51 | `
52 | },
53 |
54 | {
55 | title: 'Why the name?',
56 | slug: 'why-the-name',
57 | html: `
58 | In war, the soldiers who build bridges, repair roads, clear minefields and conduct demolitions — all under combat conditions — are known as sappers .
59 |
60 | For web developers, the stakes are generally lower than those for combat engineers. But we face our own hostile environment: underpowered devices, poor network connections, and the complexity inherent in front-end engineering. Sapper, which is short for S velte app maker , is your courageous and dutiful ally.
61 | `
62 | },
63 |
64 | {
65 | title: 'How is Sapper different from Next.js?',
66 | slug: 'how-is-sapper-different-from-next',
67 | html: `
68 | Next.js is a React framework from Zeit , and is the inspiration for Sapper. There are a few notable differences, however:
69 |
70 |
71 | It's powered by Svelte instead of React, so it's faster and your apps are smaller
72 | Instead of route masking, we encode route parameters in filenames. For example, the page you're looking at right now is src/routes/blog/[slug].html
73 | As well as pages (Svelte components, which render on server or client), you can create server routes in your routes
directory. These are just .js
files that export functions corresponding to HTTP methods, and receive Express request
and response
objects as arguments. This makes it very easy to, for example, add a JSON API such as the one powering this very page
74 | Links are just <a>
elements, rather than framework-specific <Link>
components. That means, for example, that this link right here , despite being inside a blob of HTML, works with the router as you'd expect.
75 |
76 | `
77 | },
78 |
79 | {
80 | title: 'How can I get involved?',
81 | slug: 'how-can-i-get-involved',
82 | html: `
83 | We're so glad you asked! Come on over to the Svelte and Sapper repos, and join us in the Discord chatroom . Everyone is welcome, especially you!
84 | `
85 | }
86 | ];
87 |
88 | posts.forEach(post => {
89 | post.html = post.html.replace(/^\t{3}/gm, '');
90 | });
91 |
92 | export default posts;
93 |
--------------------------------------------------------------------------------
/docs/src/routes/blog/index.json.js:
--------------------------------------------------------------------------------
1 | import posts from './_posts.js';
2 |
3 | const contents = JSON.stringify(posts.map(post => {
4 | return {
5 | title: post.title,
6 | slug: post.slug
7 | };
8 | }));
9 |
10 | export function get(req, res) {
11 | res.writeHead(200, {
12 | 'Content-Type': 'application/json'
13 | });
14 |
15 | res.end(contents);
16 | }
--------------------------------------------------------------------------------
/docs/src/routes/blog/index.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
12 |
13 |
19 |
20 |
21 | Blog
22 |
23 |
24 | Recent posts
25 |
26 |
27 | {#each posts as post}
28 |
32 | {post.title}
33 | {/each}
34 |
--------------------------------------------------------------------------------
/docs/src/routes/bulma/hero.svelte:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 |
22 |
23 | import { slide } from 'svelte/transition'
24 |
25 | const types = ['is-primary', 'is-success', 'is-danger', 'is-warning', 'is-info', 'is-link']
26 | let type = 'is-primary'
27 |
28 | async function update() {
29 | type = ''
30 |
31 | setTimeout(() => {
32 | type = types[Math.floor(Math.random() * types.length)];
33 | }, 1000)
34 | }
35 |
36 |
37 | Update Hero
38 |
39 |
40 |
41 |
42 | {#if type}
43 |
44 |
45 |
46 |
47 | Title
48 |
49 |
50 | Subtitle
51 |
52 |
53 |
54 |
55 | {/if}`}>
56 |
57 |
Update Hero
58 |
59 |
60 |
61 |
62 | {#if type}
63 |
64 |
65 |
66 |
67 | Title
68 |
69 |
70 | Subtitle
71 |
72 |
73 |
74 |
75 | {/if}
76 |
77 |
78 |
--------------------------------------------------------------------------------
/docs/src/routes/bulma/intro.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 | Many Bulma components are easy to use with regular Svelte code, without needing an additional layer of a Svelma component. The docs in this section go over how to use
9 | some of these elements in Svelte.
10 |
--------------------------------------------------------------------------------
/docs/src/routes/bulma/media.svelte:
--------------------------------------------------------------------------------
1 |
20 |
21 |
22 |
23 |
24 | import { onDestroy, onMount } from 'svelte'
25 | import { fade } from 'svelte/transition'
26 |
27 | let user
28 |
29 | const titleize = s => s.replace(/^([a-z])/, (_, r) => r.toUpperCase())
30 |
31 | async function updateUser() {
32 | user = null
33 | user = (await (await fetch('https://randomuser.me/api/')).json()).results[0]
34 | }
35 |
36 |
37 | Fetch New User
38 |
39 |
40 |
41 |
42 |
43 |
44 |
51 |
52 |
53 | {#if user}
54 |
55 | {titleize(user.name.first)} {titleize(user.name.last)}
56 | @{user.login.username}
57 |
58 |
59 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean efficitur sit amet massa fringilla
60 | egestas. Nullam condimentum luctus turpis.
61 |
62 | {/if}
63 |
64 | {#if user}
65 |
66 |
83 |
84 | {/if}
85 |
86 |
87 |
`}>
88 |
89 |
Fetch New User
90 |
91 |
92 |
93 |
94 |
95 |
96 |
103 |
104 |
105 | {#if user}
106 |
107 | {titleize(user.name.first)} {titleize(user.name.last)}
108 | @{user.login.username}
109 |
110 |
111 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean efficitur sit amet massa fringilla
112 | egestas. Nullam condimentum luctus turpis.
113 |
114 | {/if}
115 |
116 | {#if user}
117 |
118 |
135 |
136 | {/if}
137 |
138 |
139 |
140 |
141 |
142 |
--------------------------------------------------------------------------------
/docs/src/routes/bulma/table.svelte:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 | let loading = false
28 | let users = []
29 |
30 | const titleize = s => s.replace(/^([a-z])/, (_, r) => r.toUpperCase())
31 |
32 | async function update() {
33 | loading = true
34 |
35 | users = []
36 | users = (await (await fetch('https://randomuser.me/api/?results=10')).json()).results
37 |
38 | loading = false
39 | }
40 |
41 | onMount(() => update())
42 |
43 |
44 | Update
45 | users = []}>No Data
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | First Name
55 | Last Name
56 | City
57 | State
58 |
59 |
60 |
61 | {#each users as user}
62 |
63 |
64 | {titleize(user.name.first)}
65 | {titleize(user.name.last)}
66 | {titleize(user.location.city)}
67 | {titleize(user.location.state)}
68 |
69 | {:else}
70 | {#if !loading}
71 |
72 |
73 |
79 |
80 |
81 | {/if}
82 | {/each}
83 |
84 |
`}>
85 |
86 |
Update
87 |
users = []}>No Data
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | First Name
97 | Last Name
98 | City
99 | State
100 |
101 |
102 |
103 | {#each users as user}
104 |
105 |
106 | {titleize(user.name.first)}
107 | {titleize(user.name.last)}
108 | {titleize(user.location.city)}
109 | {titleize(user.location.state)}
110 |
111 | {:else}
112 | {#if !loading}
113 |
114 |
115 |
116 |
117 |
118 |
No data
119 |
120 |
121 |
122 |
123 | {/if}
124 | {/each}
125 |
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/docs/src/routes/bulma/tiles.svelte:
--------------------------------------------------------------------------------
1 |
29 |
30 |
40 |
41 |
42 |
43 |
44 | import { onMount } from 'svelte'
45 |
46 | waitForDraggabilly() {
47 | return new Promise((resolve, reject) => {
48 | const interval = setInterval({
49 | if (Draggabilly) {
50 | clearInterval(interval);
51 | resolve();
52 | }
53 | }, 100);
54 | });
55 | }
56 |
57 | onMount(async () => {
58 | const draggables = document.querySelectorAll('.tile.is-child');
59 |
60 | await waitForDraggabilly();
61 |
62 | for (const elm of draggables) {
63 | let drag = new Draggabilly(elm, {
64 | containment: '.tile.is-ancestor',
65 | });
66 | }
67 | })
68 |
69 |
70 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | Vertical...
89 | Top tile
90 |
91 |
92 | ...tiles
93 | Bottom tile
94 |
95 |
96 |
97 |
98 | Middle tile
99 | With an image
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | Wide tile
109 | Aligned with the right tile
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
Tall tile
120 |
With even more content
121 |
122 |
123 |
124 |
125 |
126 |
127 |
`}>
128 |
129 |
130 |
131 |
Click to drag tiles
132 |
133 |
134 |
135 |
136 |
137 |
138 | Vertical...
139 | Top tile
140 |
141 |
142 | ...tiles
143 | Bottom tile
144 |
145 |
146 |
147 |
148 | Middle tile
149 | With an image
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 | Wide tile
159 | Aligned with the right tile
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
Tall tile
170 |
With even more content
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
--------------------------------------------------------------------------------
/docs/src/routes/components/[slug].json.js:
--------------------------------------------------------------------------------
1 | import jsdocs from './jsdocs.json'
2 |
3 | const titleize = s => s.replace(/^([a-z])/, (_, r) => r.toUpperCase())
4 |
5 | export async function get(req, res, next) {
6 | const { slug } = req.params;
7 |
8 | res.setHeader('Content-Type', 'application/json');
9 | res.end(
10 | JSON.stringify(
11 | jsdocs[titleize(slug)]
12 | )
13 | );
14 | }
--------------------------------------------------------------------------------
/docs/src/routes/components/button.svelte:
--------------------------------------------------------------------------------
1 |
9 |
10 |
21 |
22 |
29 |
30 |
31 |
32 | counter++}>
34 | Click!: {counter}
35 | `}>
36 |
37 | counter++}>Click!: {counter}
38 |
39 |
40 |
41 |
42 |
43 | States, styles, and types
44 |
45 |
47 | Primary
48 | Success
49 | Danger
50 | Warning
51 | Info
52 | Link
53 | Light
54 | Dark
55 | Text
56 |
57 |
58 | Disabled
59 | Loading
60 | Rounded
61 | Outlined
62 |
63 |
69 |
70 | Submit
71 | Reset
72 |
`}>
73 |
74 |
75 | Primary
76 | Success
77 | Danger
78 | Warning
79 | Info
80 | Link
81 | Light
82 | Dark
83 | Text
84 |
85 |
86 | Disabled
87 | Loading
88 | Rounded
89 | Outlined
90 |
91 |
97 |
98 | Submit
99 | Reset
100 |
101 |
102 |
103 |
104 |
105 |
106 | Sizes
107 |
108 |
110 | Small
111 | Default
112 | Medium
113 | Large
114 | `}>
115 |
116 |
117 | Small
118 | Default
119 | Medium
120 | Large
121 |
122 |
123 |
124 |
125 |
126 |
127 | Icons
128 |
129 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 | GitHub
143 | Twitter
144 | Save
145 | Delete
146 |
147 |
148 | GitHub
149 | GitHub
150 | GitHub
151 | GitHub
152 |
`}>
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 | GitHub
167 | Twitter
168 | Save
169 | Delete
170 |
171 |
172 | GitHub
173 | GitHub
174 | GitHub
175 | GitHub
176 |
177 |
178 |
179 |
180 |
181 |
--------------------------------------------------------------------------------
/docs/src/routes/components/collapse.svelte:
--------------------------------------------------------------------------------
1 |
9 |
10 |
18 |
19 |
20 |
21 |
22 | import { Collapse } from 'svelma'
23 |
24 |
25 |
26 |
27 | Click Me!
28 |
29 |
30 |
31 |
Subtitle
32 |
Lorem ipsum dolor...
33 |
34 |
35 | `}>
36 |
37 |
38 | Click Me!
39 |
40 |
41 |
Subtitle
42 |
Lorem ipsum dolor...
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/docs/src/routes/components/dialog.svelte:
--------------------------------------------------------------------------------
1 |
9 |
10 |
49 |
50 |
51 |
52 | Alert and Dialog
53 |
54 | Use Dialog.alert()
and Dialog.confirm()
to create these kinds of dialogs.
55 | The methods return a promise that is resolved when the user cancels or confirms the alert. If the use closes/cancels the
56 | value will be false
. If the user clicks the confirm button the value will be true
.
57 |
58 | The first argument can either be an object of options or a string to use as the message.
59 |
60 |
61 | import { Button, Dialog, Toast } from 'svelma'
62 |
63 | function alert() {
64 | Dialog.alert('Alles ist gut')
65 | }
66 |
67 | const thenHandler = result => Toast.create(\`You \${result ? 'confirmed' : 'canceled'}\`)
68 |
69 | function confirm(type) {
70 | switch(type) {
71 | case 'custom':
72 | return Dialog.confirm({
73 | message: 'This is a custom confirmation message',
74 | title: "I'm a title!",
75 | type: 'is-danger',
76 | icon: 'times-circle'
77 | })
78 | .then(thenHandler)
79 | default:
80 | Dialog.confirm('Shall we dance?')
81 | .then(thenHandler)
82 | }
83 | }
84 |
85 |
86 | alert()}>Dialog
87 | confirm()}>Confirm
88 | confirm('custom')}>Confirm (custom)
89 | `}>
90 |
91 | alert()}>Dialog
92 | confirm()}>Confirm
93 | confirm('custom')}>Confirm (custom)
94 |
95 |
96 |
97 |
98 |
99 | Prompt
100 |
101 | Use Dialog.prompt()
to programmatically create prompts for user input. By default the
102 | dialog will be created with a required text input. You can control the props (attributes) on the prompt with the
103 | inputProps
prop.
104 |
105 | prompt()
returns a promise that will be resolved with the prompt input value if the user confirms, or null
106 | if they cancel/close.
107 |
108 |
109 | import { Button, Dialog, Toast } from 'svelma'
110 |
111 | function prompt(opts) {
112 | Dialog.prompt({
113 | message: "What is your quest?",
114 | ...opts
115 | })
116 | .then(prompt => Toast.create(\`Your answer was: '\${prompt}'\`))
117 | }
118 |
119 |
120 | prompt()}>Prompt
121 | prompt({ message: 'Which date?', inputProps: { type: 'date' }})}>Date Prompt `
122 | }>
123 |
124 | prompt()}>Prompt
125 | prompt({ message: 'Which date?', inputProps: { type: 'date' }})}>Date Prompt
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/docs/src/routes/components/icon.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 | import { Icon } from 'svelma'
11 |
12 |
13 |
14 | `}>
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/docs/src/routes/components/input.svelte:
--------------------------------------------------------------------------------
1 |
9 |
10 |
26 |
27 |
28 |
29 |
30 | Mostly just wraps {` `}
and {`
so additional Bulma features can be bound easily.
31 |
32 |
33 |
34 |
35 |
36 | import { Input } from 'svelma'
37 |
38 |
39 |
40 | `}>
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | Types and colors
49 |
50 | Wrap with Field for additional features
51 |
52 |
53 | import { Field, Input } from 'svelma'
54 |
55 | let bound = {
56 | name: 'Rich Harris',
57 | email: 'rich@',
58 | username: 'richie55',
59 | password: 'secret123',
60 | }
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | `}>
83 |
84 |
85 | // Bound values
86 | {JSON.stringify(bound, null, 2)}
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 | States, plus more styles
116 |
117 |
118 | import { Field, Input } from 'svelma'
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 | `}>
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 | Sizes
174 |
175 |
176 | import { Field, Input } from 'svelma'
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 | `}>
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
--------------------------------------------------------------------------------
/docs/src/routes/components/message.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 | import { Button, Message } from 'svelma'
13 |
14 | let open
15 |
16 |
17 | open = !open}>Toggle
18 | open = active}>
20 | Lorem ipsum dolor sit amet, consectetur adipiscing elit.
21 | Fusce id fermentum quam. Proin sagittis, nibh id
22 | hendrerit imperdiet, elit sapien laoreet elit
23 | `}>
24 |
25 | open = !open}>Toggle
26 | open = active}
28 | >
29 | Lorem ipsum dolor sit amet, consectetur adipiscing elit.
30 | Fusce id fermentum quam. Proin sagittis, nibh id
31 | hendrerit imperdiet, elit sapien laoreet elit
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/docs/src/routes/components/modal.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 | import { Button, Modal } from 'svelma'
13 |
14 | let active = false
15 |
16 |
17 | active = !active}>Toggle
18 |
19 |
20 |
21 |
22 | `}>
23 |
24 |
active = !active}>Toggle
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/docs/src/routes/components/modalcard.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 | import { Button, ModalCard } from 'svelma'
13 |
14 | let active = false
15 |
16 |
17 | active = !active}>Toggle
18 |
19 |
20 |
21 |
22 | `}>
23 |
24 |
active = !active}>Toggle
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/docs/src/routes/components/progress.svelte:
--------------------------------------------------------------------------------
1 |
21 |
22 |
23 |
24 |
25 | import { onDestroy, onMount } from 'svelte'
26 | import { Progress } from 'svelma'
27 |
28 | const types = ['is-primary', 'is-success', 'is-danger', 'is-warning', 'is-info', 'is-link']
29 | const progresses = Array(6).fill(0)
30 |
31 | function update() {
32 | types.forEach((type, i) => {
33 | progresses[i] = Math.floor(Math.random() * 100)
34 | })
35 | }
36 |
37 | onMount(() => {
38 | update()
39 | })
40 |
41 |
42 | Update
43 |
44 |
45 |
46 |
47 | {#each types as type, i}
48 |
49 | {/each}
50 |
51 |
52 |
53 |
54 | Indeterminate (no value)
55 | `}>
56 |
57 |
Update
58 |
59 |
60 |
61 |
62 | {#each types as type, i}
63 |
64 | {/each}
65 |
66 |
67 |
68 |
69 |
Indeterminate (no value)
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/docs/src/routes/components/snackbar.svelte:
--------------------------------------------------------------------------------
1 |
9 |
10 |
22 |
23 |
30 |
31 |
32 |
33 |
34 | import { Button, Snackbar } from 'svelma'
35 |
36 | function open(props) {
37 | Snackbar.create({ message: 'I am a snackbar message', ...props })
38 | }
39 |
40 |
41 |
42 | open()}>Default Snackbar
43 | open({ type: 'is-success' })}>Success
44 | open({ type: 'is-danger', actionText: 'retry', position: 'is-top-right' })}>Top Right
45 | open({ background: 'has-background-grey-lighter' })}>Custom Background
46 |
`}>
47 |
48 |
49 | open()}>Default Snackbar
50 | open({ type: 'is-success' })}>Success
51 | open({ type: 'is-danger', actionText: 'retry', position: 'is-top-right' })}>Top Right
52 | open({ background: 'has-background-grey-lighter' })}>Custom Background
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/docs/src/routes/components/switch.svelte:
--------------------------------------------------------------------------------
1 |
9 |
10 |
19 |
20 |
21 |
22 |
23 | import { Switch } from 'svelma'
24 |
25 | let val
26 |
27 |
28 |
29 | Foo
30 |
31 | value = {JSON.stringify(val)}
32 |
33 |
34 | Disabled
35 |
36 | `}>
37 |
38 |
39 | Foo
40 |
41 | value = {JSON.stringify(val)}
42 |
43 |
44 | Disabled
45 |
46 |
47 |
48 |
49 |
50 | Types
51 |
52 |
53 | import { Switch } from 'svelma'
54 |
55 |
56 |
57 | Primary
58 |
59 |
60 | Danger
61 |
62 |
63 | Warning
64 |
65 |
66 | Info
67 |
68 |
69 | Link
70 |
71 |
72 | Dark
73 |
74 | `}>
75 |
76 |
77 | Primary
78 |
79 |
80 | Danger
81 |
82 |
83 | Warning
84 |
85 |
86 | Info
87 |
88 |
89 | Link
90 |
91 |
92 | Dark
93 |
94 |
95 |
96 |
97 |
98 | Sizes
99 |
100 |
101 | import { Switch } from 'svelma'
102 |
103 |
104 |
105 | Small
106 |
107 |
108 | Default
109 |
110 |
111 | Medium
112 |
113 |
114 | Large
115 |
116 |
117 | `}>
118 |
119 |
120 | Small
121 |
122 |
123 | Default
124 |
125 |
126 | Medium
127 |
128 |
129 | Large
130 |
131 |
132 |
133 |
134 |
--------------------------------------------------------------------------------
/docs/src/routes/components/tag.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
25 |
26 |
44 |
45 |
46 |
47 |
49 | import { Tag } from 'svelma'
50 |
51 |
52 | Tag label
53 | Rounded tag label `}>
54 |
55 |
56 |
57 | Tag label
58 | Rounded tag label
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | Closable tags have a button that can be focused, it emits a close event when clicked or when delete key is pressed.
67 | Closable
68 |
69 |
71 | import { Tag } from 'svelma'
72 |
73 | let isTag1Active = true
74 | let isTag2Active = true
75 | let isTag3Active = true
76 |
77 |
78 |
79 | {#if isTag1Active}
80 | isTag1Active = false}>
83 | Colored closable tag label
84 |
85 | {/if}
86 |
87 |
88 |
89 | {#if isTag2Active}
90 | isTag2Active = false}>
92 | Attached closable tag label
93 |
94 | {/if}
95 |
96 |
97 |
98 | {#if isTag3Active}
99 | isTag3Active = false}>
102 | Colored attached closable tag label
103 |
104 | {/if}
105 |
`}>
106 |
107 |
128 |
129 |
130 |
131 |
132 |
133 | Taglist
134 |
135 |
136 |
138 | import { Tag, Taglist } from 'svelma'
139 |
140 |
141 |
142 | First
143 | Second
144 | Third
145 | Fourth
146 | Fifth
147 | `}>
148 |
149 |
150 |
151 | First
152 | Second
153 | Third
154 | Fourth
155 | Fifth
156 |
157 |
158 |
159 |
160 |
161 |
162 | Use the attached
prop to attach tags together.
163 |
164 |
166 | import { Tag, Taglist } from 'svelma'
167 |
168 |
169 |
170 | npm
171 | 0.2.1
172 | `}>
173 |
174 |
175 |
176 | npm
177 | 0.2.1
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 | API
186 |
187 | Tag
188 |
189 |
190 |
191 |
192 |
193 | Taglist
194 |
--------------------------------------------------------------------------------
/docs/src/routes/components/toast.svelte:
--------------------------------------------------------------------------------
1 |
9 |
10 |
22 |
23 |
30 |
31 |
32 |
33 |
34 | import { Button, Toast } from 'svelma'
35 |
36 | function open(type, position) {
37 | Toast.create({ message: 'I am a toast', type, position })
38 | }
39 |
40 |
41 | open()}>Toast
42 | open('is-success')}>Success
43 | open('is-danger', 'is-bottom-right')}>Bottom Right
44 | open('is-primary', 'is-top', 'has-background-grey-lighter')}>Custom Background `}>
45 |
46 |
47 | open()}>Toast
48 | open('is-success')}>Success
49 | open('is-danger', 'is-bottom-right')}>Bottom Right
50 | open('is-primary', 'is-top', 'has-background-grey-lighter')}>Custom Background
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/docs/src/routes/components/tooltip.svelte:
--------------------------------------------------------------------------------
1 |
9 |
10 |
19 |
20 |
27 |
28 |
29 |
30 |
32 | import { Button, Tooltip} from 'svelma'
33 |
34 |
35 |
36 | Left
37 |
38 |
39 |
40 | Top (default)
41 |
42 |
43 |
44 | Bottom
45 |
46 |
47 |
48 | Right
49 | `}>
50 |
51 |
52 |
53 |
54 | Left
55 |
56 |
57 |
58 | Top (default)
59 |
60 |
61 |
62 | Bottom
63 |
64 |
65 |
66 | Right
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | Sizes
75 |
76 | Small
78 | Medium
79 | Large `}>
80 |
81 |
82 |
83 | Small
84 |
85 |
86 |
87 | Medium
88 |
89 |
90 |
91 | Large
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 | Color
100 |
101 | Primary
103 | Success
104 | Danger
105 | Warning
106 | Info
107 | Link
108 | Light
109 | Dark `}>
110 |
111 |
112 |
113 | Primary
114 |
115 |
116 |
117 | Success
118 |
119 |
120 |
121 | Danger
122 |
123 |
124 |
125 | Warning
126 |
127 |
128 |
129 | Info
130 |
131 |
132 |
133 | Link
134 |
135 |
136 |
137 | Light
138 |
139 |
140 |
141 | Dark
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 | Styles
150 |
151 | Rounded
153 | Square
154 | Dashed
155 | Multilined
156 | Not Animated
157 | Inactive
158 | Always `}>
159 |
160 |
161 |
162 | Rounded
163 |
164 |
165 |
166 | Square
167 |
168 |
169 |
170 | Dashed
171 |
172 |
173 |
174 | Multilined
175 |
176 |
177 |
178 | Not Animated
179 |
180 |
181 |
182 | Inactive
183 |
184 |
185 |
186 | Always
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 | Advanced
195 |
196 | Customized Animation
198 | Custom Styles `}>
199 |
200 |
201 |
202 | Customized Animation
203 |
204 |
205 |
206 | Custom Styles
207 |
208 |
209 |
210 |
211 |
212 |
213 |
--------------------------------------------------------------------------------
/docs/src/routes/index.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
44 |
45 |
46 | Svelma
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
Svelma
56 |
Bulma components for Svelte
57 |
58 |
59 | $ npm install svelma
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | This library is a very early work-in-progress. Please forgive all broken and missing features and
68 | documentation.
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/docs/src/routes/install/index.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
71 |
72 |
73 |
74 |
83 |
--------------------------------------------------------------------------------
/docs/src/server.js:
--------------------------------------------------------------------------------
1 | import sirv from 'sirv';
2 | import polka from 'polka';
3 | import compression from 'compression';
4 | import * as sapper from '@sapper/server';
5 |
6 | const { PORT, NODE_ENV } = process.env;
7 | const dev = NODE_ENV === 'development';
8 |
9 | polka() // You can also use Express
10 | .use(...[
11 | process.env.SAPPER_EXPORT && '/svelma' || undefined,
12 | compression({ threshold: 0 }),
13 | sirv('static', { dev }),
14 | sapper.middleware()
15 | ].filter(x => !!x))
16 | .listen(PORT, err => {
17 | if (err) console.log('error', err);
18 | });
19 |
--------------------------------------------------------------------------------
/docs/src/service-worker.js:
--------------------------------------------------------------------------------
1 | import { timestamp, files, shell, routes } from '@sapper/service-worker';
2 |
3 | const ASSETS = `cache${timestamp}`;
4 |
5 | // `shell` is an array of all the files generated by the bundler,
6 | // `files` is an array of everything in the `static` directory
7 | const to_cache = shell.concat(files);
8 | const cached = new Set(to_cache);
9 |
10 | self.addEventListener('install', event => {
11 | event.waitUntil(
12 | caches
13 | .open(ASSETS)
14 | .then(cache => cache.addAll(to_cache))
15 | .then(() => {
16 | self.skipWaiting();
17 | })
18 | );
19 | });
20 |
21 | self.addEventListener('activate', event => {
22 | event.waitUntil(
23 | caches.keys().then(async keys => {
24 | // delete old caches
25 | for (const key of keys) {
26 | if (key !== ASSETS) await caches.delete(key);
27 | }
28 |
29 | self.clients.claim();
30 | })
31 | );
32 | });
33 |
34 | self.addEventListener('fetch', event => {
35 | if (event.request.method !== 'GET' || event.request.headers.has('range')) return;
36 |
37 | const url = new URL(event.request.url);
38 |
39 | // don't try to handle e.g. data: URIs
40 | if (!url.protocol.startsWith('http')) return;
41 |
42 | // ignore dev server requests
43 | if (url.hostname === self.location.hostname && url.port !== self.location.port) return;
44 |
45 | // always serve static files and bundler-generated assets from cache
46 | if (url.host === self.location.host && cached.has(url.pathname)) {
47 | event.respondWith(caches.match(event.request));
48 | return;
49 | }
50 |
51 | // for pages, you might want to serve a shell `service-worker-index.html` file,
52 | // which Sapper has generated for you. It's not right for every
53 | // app, but if it's right for yours then uncomment this section
54 | /*
55 | if (url.origin === self.origin && routes.find(route => route.pattern.test(url.pathname))) {
56 | event.respondWith(caches.match('/service-worker-index.html'));
57 | return;
58 | }
59 | */
60 |
61 | if (event.request.cache === 'only-if-cached') return;
62 |
63 | // for everything else, try the network first, falling back to
64 | // cache if the user is offline. (If the pages never change, you
65 | // might prefer a cache-first approach to a network-first one.)
66 | event.respondWith(
67 | caches
68 | .open(`offline${timestamp}`)
69 | .then(async cache => {
70 | try {
71 | const response = await fetch(event.request);
72 | cache.put(event.request, response.clone());
73 | return response;
74 | } catch(err) {
75 | const response = await cache.match(event.request);
76 | if (response) return response;
77 |
78 | throw err;
79 | }
80 | })
81 | );
82 | });
83 |
--------------------------------------------------------------------------------
/docs/src/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | %sapper.base%
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
21 | %sapper.styles%
22 |
23 |
25 | %sapper.head%
26 |
27 |
28 |
30 | %sapper.html%
31 |
32 |
35 | %sapper.scripts%
36 |
37 |
38 |
--------------------------------------------------------------------------------
/docs/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/c0bra/svelma/ddd412e79085f47646b3739f5d05277219f070a2/docs/static/favicon.ico
--------------------------------------------------------------------------------
/docs/static/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/c0bra/svelma/ddd412e79085f47646b3739f5d05277219f070a2/docs/static/favicon.png
--------------------------------------------------------------------------------
/docs/static/global.css:
--------------------------------------------------------------------------------
1 | /* body {
2 | margin: 0;
3 | font-family: Roboto, -apple-system, BlinkMacSystemFont, Segoe UI, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans,
4 | Helvetica Neue, sans-serif;
5 | font-size: 14px;
6 | line-height: 1.5;
7 | color: #333;
8 | }
9 |
10 | h1,
11 | h2,
12 | h3,
13 | h4,
14 | h5,
15 | h6 {
16 | margin: 0 0 0.5em 0;
17 | font-weight: 400;
18 | line-height: 1.2;
19 | }
20 |
21 | h1 {
22 | font-size: 2em;
23 | }
24 |
25 | a {
26 | color: inherit;
27 | }
28 |
29 | code {
30 | font-family: menlo, inconsolata, monospace;
31 | font-size: calc(1em - 2px);
32 | color: #555;
33 | background-color: #f0f0f0;
34 | padding: 0.2em 0.4em;
35 | border-radius: 2px;
36 | }
37 |
38 | @media (min-width: 400px) {
39 | body {
40 | font-size: 16px;
41 | }
42 | } */
43 |
44 | header.header {
45 | border-bottom: 2px solid #f5f5f5;
46 | margin-bottom: 3rem;
47 | padding-bottom: 3rem;
48 | }
49 |
50 | header.header .subtitle {
51 | color: #7a7a7a;
52 | }
53 |
54 | hr.is-medium {
55 | margin: 3rem 0
56 | }
57 |
58 | .control .icon.is-clickable, .control.has-icons-left .icon.is-clickable, .control.has-icons-right .icon.is-clickable {
59 | pointer-events: auto;
60 | cursor: pointer;
61 | }
--------------------------------------------------------------------------------
/docs/static/great-success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/c0bra/svelma/ddd412e79085f47646b3739f5d05277219f070a2/docs/static/great-success.png
--------------------------------------------------------------------------------
/docs/static/logo-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/c0bra/svelma/ddd412e79085f47646b3739f5d05277219f070a2/docs/static/logo-192.png
--------------------------------------------------------------------------------
/docs/static/logo-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/c0bra/svelma/ddd412e79085f47646b3739f5d05277219f070a2/docs/static/logo-512.png
--------------------------------------------------------------------------------
/docs/static/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "background_color": "#ffffff",
3 | "theme_color": "#333333",
4 | "name": "Svelma",
5 | "short_name": "Svelma",
6 | "display": "minimal-ui",
7 | "start_url": "/",
8 | "icons": [
9 | {
10 | "src": "logo-192.png",
11 | "sizes": "192x192",
12 | "type": "image/png"
13 | },
14 | {
15 | "src": "logo-512.png",
16 | "sizes": "512x512",
17 | "type": "image/png"
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/docs/static/svelma-logo-ico.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/c0bra/svelma/ddd412e79085f47646b3739f5d05277219f070a2/docs/static/svelma-logo-ico.png
--------------------------------------------------------------------------------
/docs/static/svelma-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/c0bra/svelma/ddd412e79085f47646b3739f5d05277219f070a2/docs/static/svelma-logo.png
--------------------------------------------------------------------------------
/docs/static/svelma-logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
20 |
22 |
23 |
25 | image/svg+xml
26 |
28 |
29 |
30 |
31 |
32 |
56 |
58 |
60 |
66 |
67 |
68 |
74 |
80 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "svelma",
3 | "svelte": "src/index.js",
4 | "description": "Bulma components for Svelte",
5 | "version": "0.4.5",
6 | "author": "Abby Chau, Brian Hann",
7 | "license": "MIT",
8 | "keywords": [
9 | "svelte",
10 | "svelte.js",
11 | "sveltejs",
12 | "bulma",
13 | "component",
14 | "components"
15 | ],
16 | "repository": {
17 | "type": "git",
18 | "url": "git+https://github.com/c0bra/svelma.git"
19 | },
20 | "bugs": {
21 | "url": "https://github.com/c0bra/svelma/issues"
22 | },
23 | "module": "dist/module.js",
24 | "main": "dist/index.js",
25 | "files": [
26 | "dist",
27 | "src"
28 | ],
29 | "peerDependencies": {
30 | "bulma": "^0.9.3"
31 | },
32 | "devDependencies": {
33 | "@rollup/plugin-alias": "3.1.9",
34 | "@rollup/plugin-commonjs": "21.0.1",
35 | "@rollup/plugin-node-resolve": "13.1.3",
36 | "autoprefixer": "^10.4.1",
37 | "bulma": "^0.9.3",
38 | "conventional-changelog-cli": "^2.2.2",
39 | "get-port-cli": "^3.0.0",
40 | "node-sass": "^7.0.1",
41 | "npm-run-all": "^4.1.5",
42 | "postcss": "^8.4.5",
43 | "prettier": "^2.5.1",
44 | "prettier-plugin-svelte": "^2.5.1",
45 | "rollup": "^2.63.0",
46 | "rollup-plugin-bundle-size": "^1.0.3",
47 | "rollup-plugin-copy": "^3.4.0",
48 | "rollup-plugin-css-only": "^3.1.0",
49 | "rollup-plugin-livereload": "^2.0.5",
50 | "rollup-plugin-scss": "^3.0.0",
51 | "rollup-plugin-svelte": "^7.1.0",
52 | "rollup-plugin-terser": "^7.0.2",
53 | "semantic-release": "^19.0.3",
54 | "sirv-cli": "^2.0.1",
55 | "standard-version": "^9.3.2",
56 | "svelte": "^3.44.3",
57 | "svelte-preprocess": "^4.10.1",
58 | "wait-for-localhost-cli": "^3.0.0"
59 | },
60 | "scripts": {
61 | "build": "rollup -c",
62 | "autobuild": "rollup -c -w",
63 | "dev": "run-p autobuild autodocs",
64 | "docs": "(cd docs; npm i -f; npx sapper export --basepath svelma)",
65 | "autodocs": "(cd docs; npx sapper dev --basepath svelma)",
66 | "jsdocs": "(cd docs; npx jsdoc -c jsdoc/conf.js)",
67 | "prepublishOnly": "npm run build",
68 | "changelog": "conventional-changelog -i CHANGELOG.md -p angular",
69 | "semantic-release": "semantic-release"
70 | },
71 | "browserslist": "last 2 versions",
72 | "homepage": "https://github.com/c0bra/svelma#readme",
73 | "directories": {
74 | "doc": "docs"
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/c0bra/svelma/ddd412e79085f47646b3739f5d05277219f070a2/public/favicon.png
--------------------------------------------------------------------------------
/public/global.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | position: relative;
3 | width: 100%;
4 | height: 100%;
5 | }
6 |
7 | body {
8 | color: #333;
9 | margin: 0;
10 | padding: 8px;
11 | box-sizing: border-box;
12 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
13 | }
14 |
15 | a {
16 | color: rgb(0,100,200);
17 | text-decoration: none;
18 | }
19 |
20 | a:hover {
21 | text-decoration: underline;
22 | }
23 |
24 | a:visited {
25 | color: rgb(0,80,160);
26 | }
27 |
28 | label {
29 | display: block;
30 | }
31 |
32 | input, button, select, textarea {
33 | font-family: inherit;
34 | font-size: inherit;
35 | padding: 0.4em;
36 | margin: 0 0 0.5em 0;
37 | box-sizing: border-box;
38 | border: 1px solid #ccc;
39 | border-radius: 2px;
40 | }
41 |
42 | input:disabled {
43 | color: #ccc;
44 | }
45 |
46 | input[type="range"] {
47 | height: 0;
48 | }
49 |
50 | button {
51 | background-color: #f4f4f4;
52 | outline: none;
53 | }
54 |
55 | button:active {
56 | background-color: #ddd;
57 | }
58 |
59 | button:focus {
60 | border-color: #666;
61 | }
62 |
63 | hr.is-medium {
64 | margin: 3rem 0
65 | }
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Svelte app
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import autoPreprocess from 'svelte-preprocess'
2 | import bundleSize from 'rollup-plugin-bundle-size'
3 | import commonjs from '@rollup/plugin-commonjs'
4 | import resolve from '@rollup/plugin-node-resolve'
5 | import svelte from 'rollup-plugin-svelte'
6 | import { terser } from 'rollup-plugin-terser'
7 | import pkg from './package.json'
8 | import css from 'rollup-plugin-css-only'
9 |
10 | const production = !process.env.ROLLUP_WATCH
11 |
12 | const { name } = pkg
13 |
14 | export default {
15 | input: 'src/index.js',
16 | output: {
17 | sourcemap: true,
18 | format: 'iife',
19 | name: name,
20 | file: 'public/build/bundle.js'
21 | },
22 | plugins: [
23 | css({ output: 'bundle.css' }),
24 | svelte({
25 | // enable run-time checks when not in production
26 | compilerOptions: {
27 | hydratable: true,
28 | dev: !production,
29 | },
30 | preprocess: autoPreprocess({
31 | postcss: {
32 | plugins: [require('autoprefixer')()],
33 | },
34 | })
35 | }),
36 |
37 | resolve(),
38 | commonjs(),
39 |
40 | production && terser(),
41 |
42 | // production && analyze(),
43 | production && bundleSize(),
44 | ],
45 | watch: {
46 | clearScreen: false,
47 | },
48 | }
49 |
--------------------------------------------------------------------------------
/src/components/Button.svelte:
--------------------------------------------------------------------------------
1 |
65 |
66 | {#if tag === 'button'}
67 |
75 | {#if iconLeft}
76 |
77 | {/if}
78 |
79 |
80 |
81 | {#if iconRight}
82 |
83 | {/if}
84 |
85 | {:else if tag === 'a'}
86 |
94 | {#if iconLeft}
95 |
96 | {/if}
97 |
98 |
99 |
100 | {#if iconRight}
101 |
102 | {/if}
103 |
104 | {/if}
105 |
--------------------------------------------------------------------------------
/src/components/Collapse.svelte:
--------------------------------------------------------------------------------
1 |
22 |
23 |
24 |
25 |
26 |
27 | {#if open}
28 |
29 |
30 |
31 | {/if}
32 |
33 |
--------------------------------------------------------------------------------
/src/components/Dialog/Dialog.svelte:
--------------------------------------------------------------------------------
1 |
156 |
157 |
215 |
216 |
217 |
218 |
219 | {#if active}
220 |
221 |
222 |
223 | {#if title}
224 |
225 | {title}
226 |
227 |
230 |
231 | {/if}
232 |
258 |
259 |
275 |
276 |
277 | {/if}
278 |
--------------------------------------------------------------------------------
/src/components/Dialog/index.js:
--------------------------------------------------------------------------------
1 | import Dialog from './Dialog.svelte'
2 |
3 | function createDialog(props) {
4 | if (typeof props === 'string') props = { message: props }
5 |
6 | const dialog = new Dialog({
7 | target: document.body,
8 | props,
9 | intro: true,
10 | });
11 |
12 | dialog.$on('destroy', () => {
13 | dialog.$destroy()
14 | })
15 |
16 | return dialog.promise
17 | }
18 |
19 | export function alert(props) {
20 | return createDialog(props);
21 | }
22 |
23 | export function confirm(props) {
24 | if (typeof props === 'string') props = { message: props }
25 |
26 | return createDialog({ showCancel: true, ...props });
27 | }
28 |
29 | export function prompt(props) {
30 | if (typeof props === 'string') props = { message: props }
31 |
32 | return createDialog({ hasInput: true, confirmText: 'Done', ...props });
33 | }
34 |
35 | Dialog.alert = alert
36 | Dialog.confirm = confirm
37 | Dialog.prompt = prompt
38 |
39 | export default Dialog
--------------------------------------------------------------------------------
/src/components/Dropdown.svelte:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 |
17 |
18 |
19 | {#if open}
20 |
21 |
22 |
23 | {/if}
24 |
25 |
--------------------------------------------------------------------------------
/src/components/Field.svelte:
--------------------------------------------------------------------------------
1 |
97 |
98 |
116 |
117 |
118 | {#if label}
119 |
{label}
120 | {/if}
121 |
122 | {#if message}
123 |
{message}
124 | {/if}
125 |
126 |
--------------------------------------------------------------------------------
/src/components/File.svelte:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Choose a file…
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/components/Icon.svelte:
--------------------------------------------------------------------------------
1 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/src/components/Input.svelte:
--------------------------------------------------------------------------------
1 |
138 |
139 |
145 |
146 |
147 |
148 | {#if type !== 'textarea'}
149 |
161 | {:else}
162 |
174 | {/if}
175 |
176 | {#if icon}
177 |
181 | {/if}
182 |
183 | {#if !loading && (passwordReveal || statusType)}
184 |
186 |
193 | {/if}
194 |
195 | {#if maxlength && hasCounter && type !== 'number'}
196 | {valueLength} / {maxlength}
197 | {/if}
198 |
199 |
--------------------------------------------------------------------------------
/src/components/Message.svelte:
--------------------------------------------------------------------------------
1 |
52 |
53 |
63 |
64 | {#if active}
65 |
66 | {#if title || showClose}
67 |
75 | {/if}
76 |
88 |
89 | {/if}
90 |
--------------------------------------------------------------------------------
/src/components/Modal/Modal.svelte:
--------------------------------------------------------------------------------
1 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | {#if showClose}
45 |
46 | {/if}
47 |
48 |
--------------------------------------------------------------------------------
/src/components/Modal/ModalCard.svelte:
--------------------------------------------------------------------------------
1 |
45 |
46 |
47 |
48 |
64 |
--------------------------------------------------------------------------------
/src/components/Modal/index.js:
--------------------------------------------------------------------------------
1 | import Modal from './Modal.svelte'
2 | import ModalCard from './ModalCard.svelte'
3 |
4 | Modal.open = open
5 | ModalCard.open = open
6 |
7 | export default Modal
8 | export { ModalCard }
9 |
10 | export function open(props) {
11 | const modal = new Modal({
12 | target: document.body,
13 | props,
14 | intro: true
15 | });
16 |
17 | modal.close = () => modal.$destroy();
18 |
19 | return modal;
20 | }
--------------------------------------------------------------------------------
/src/components/Notice.svelte:
--------------------------------------------------------------------------------
1 |
14 |
15 |
84 |
85 |
106 |
107 | {#if active}
108 |
115 |
116 |
117 |
118 | {/if}
119 |
--------------------------------------------------------------------------------
/src/components/Notices.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
16 |
17 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/src/components/Notification/Notification.svelte:
--------------------------------------------------------------------------------
1 |
86 |
87 |
93 |
94 | {#if active}
95 |
96 | {#if showClose}
97 |
98 | {/if}
99 |
109 |
110 | {/if}
111 |
--------------------------------------------------------------------------------
/src/components/Notification/NotificationNotice.svelte:
--------------------------------------------------------------------------------
1 |
26 |
27 |
32 |
33 |
34 |
35 | {@html message}
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/components/Notification/index.js:
--------------------------------------------------------------------------------
1 | import Notification from './Notification.svelte'
2 | import NotificationNotice from './NotificationNotice.svelte'
3 |
4 | Notification.create = create
5 |
6 | export default Notification
7 |
8 | export function create(props) {
9 | if (typeof props === 'string') props = { message: props }
10 |
11 | const notification = new NotificationNotice({
12 | target: document.body,
13 | props,
14 | intro: true,
15 | })
16 |
17 | notification.$on('destroyed', notification.$destroy)
18 |
19 | return notification
20 | }
21 |
--------------------------------------------------------------------------------
/src/components/Progress.svelte:
--------------------------------------------------------------------------------
1 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/components/Select.svelte:
--------------------------------------------------------------------------------
1 |
98 |
99 |
100 |
104 |
114 | {#if !multiple}
115 |
123 |
124 | {#if placeholder && selected === ''}
125 |
129 | {placeholder}
130 |
131 | {/if}
132 |
133 |
134 | {:else}
135 |
144 |
145 | {#if placeholder && selected === ''}
146 |
150 | {placeholder}
151 |
152 | {/if}
153 |
154 |
155 | {/if}
156 |
157 |
158 | {#if icon}
159 |
164 | {/if}
165 |
--------------------------------------------------------------------------------
/src/components/Snackbar/Snackbar.svelte:
--------------------------------------------------------------------------------
1 |
53 |
54 |
94 |
95 |
96 |
97 |
98 | {@html message}
99 |
100 |
101 | {#if actionText}
102 |
103 | { actionText }
104 |
105 | {/if}
106 |
107 |
108 |
--------------------------------------------------------------------------------
/src/components/Snackbar/index.js:
--------------------------------------------------------------------------------
1 | import Snackbar from './Snackbar.svelte'
2 |
3 | Snackbar.create = create
4 |
5 | export default Snackbar
6 |
7 | export function create(props) {
8 | if (typeof props === 'string') props = { message: props }
9 |
10 | const snackbar = new Snackbar({
11 | target: document.body,
12 | props,
13 | intro: true,
14 | });
15 |
16 | snackbar.$on('destroyed', snackbar.$destroy)
17 |
18 | return snackbar;
19 | }
--------------------------------------------------------------------------------
/src/components/Switch.svelte:
--------------------------------------------------------------------------------
1 |
2 |
42 |
43 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/src/components/Tabs/Tab.svelte:
--------------------------------------------------------------------------------
1 |
96 |
97 |
127 |
128 |
134 |
135 |
136 |
--------------------------------------------------------------------------------
/src/components/Tabs/Tabs.svelte:
--------------------------------------------------------------------------------
1 |
84 |
85 |
95 |
96 |
97 |
98 |
111 |
112 |
115 |
116 |
--------------------------------------------------------------------------------
/src/components/Tabs/index.js:
--------------------------------------------------------------------------------
1 | import Tabs from './Tabs.svelte'
2 | import Tab from './Tab.svelte'
3 |
4 | export default Tabs
5 |
6 | export { Tabs, Tab }
--------------------------------------------------------------------------------
/src/components/Tag/Tag.svelte:
--------------------------------------------------------------------------------
1 |
55 |
56 | {#if attached && closable}
57 |
74 | {:else}
75 |
78 |
79 |
80 |
81 | {#if closable}
82 | isDeleteKey() && close()}
88 | />
89 | {/if}
90 |
91 | {/if}
92 |
93 |
--------------------------------------------------------------------------------
/src/components/Tag/Taglist.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/components/Tag/index.js:
--------------------------------------------------------------------------------
1 | import Tag from './Tag.svelte'
2 | import Taglist from './Taglist.svelte'
3 |
4 | export default Tag
5 |
6 | export {Tag, Taglist}
--------------------------------------------------------------------------------
/src/components/Toast/Toast.svelte:
--------------------------------------------------------------------------------
1 |
38 |
39 |
49 |
50 |
51 |
52 |
53 | {@html message}
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/src/components/Toast/index.js:
--------------------------------------------------------------------------------
1 | import Toast from './Toast.svelte'
2 |
3 | Toast.create = create
4 |
5 | export default Toast
6 |
7 | export function create(props) {
8 | if (typeof props === 'string') props = { message: props }
9 |
10 | const toast = new Toast({
11 | target: document.body,
12 | props,
13 | intro: true,
14 | });
15 |
16 | toast.$on('destroyed', toast.$destroy)
17 |
18 | return toast;
19 | }
--------------------------------------------------------------------------------
/src/components/Tooltip.svelte:
--------------------------------------------------------------------------------
1 |
93 |
94 |
199 |
200 |
219 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | // import './scss/main.scss'
2 | import Button from './components/Button.svelte'
3 | import Collapse from './components/Collapse.svelte'
4 | import Dialog from './components/Dialog'
5 | import Field from './components/Field.svelte'
6 | import Icon from './components/Icon.svelte'
7 | import Input from './components/Input.svelte'
8 | import Message from './components/Message.svelte'
9 | import Modal, {ModalCard} from './components/Modal'
10 | import Notification from './components/Notification'
11 | import Progress from './components/Progress.svelte'
12 | import Select from './components/Select.svelte'
13 | import Snackbar from './components/Snackbar'
14 | import Switch from './components/Switch.svelte'
15 | import { Tabs, Tab } from './components/Tabs'
16 | import Toast from './components/Toast'
17 | import Tooltip from './components/Tooltip.svelte'
18 | import { Tag, Taglist } from './components/Tag'
19 |
20 | export {
21 | Button,
22 | Collapse,
23 | Dialog,
24 | Field,
25 | Icon,
26 | Input,
27 | Message,
28 | Notification,
29 | Progress,
30 | Modal,
31 | ModalCard,
32 | Select,
33 | Snackbar,
34 | Switch,
35 | Tabs,
36 | Tab,
37 | Tag,
38 | Taglist,
39 | Toast,
40 | Tooltip,
41 | }
42 |
43 | export const Svelma = {
44 | Button,
45 | Collapse,
46 | Dialog,
47 | Icon,
48 | Input,
49 | Field,
50 | Message,
51 | Modal,
52 | ModalCard,
53 | Notification,
54 | Progress,
55 | Select,
56 | Snackbar,
57 | Switch,
58 | Tabs,
59 | Tab,
60 | Tag,
61 | Taglist,
62 | Toast,
63 | Tooltip,
64 | }
65 |
--------------------------------------------------------------------------------
/src/utils/index.js:
--------------------------------------------------------------------------------
1 | import * as transitions from 'svelte/transition'
2 | import { bubble, listen } from "svelte/internal";
3 |
4 | export function chooseAnimation(animation) {
5 | return typeof animation === 'function' ? animation : transitions[animation]
6 | }
7 |
8 | export function isEnterKey(e) {
9 | return e.keyCode && e.keyCode === 13
10 | }
11 |
12 | export function isDeleteKey(e) {
13 | return e.keyCode && e.keyCode === 46
14 | }
15 |
16 | export function isEscKey(e) {
17 | return e.keyCode && e.keyCode === 27
18 | }
19 |
20 | export function omit(obj, ...keysToOmit) {
21 | return Object.keys(obj).reduce((acc, key) => {
22 | if (keysToOmit.indexOf(key) === -1) acc[key] = obj[key]
23 | return acc
24 | }, {})
25 | }
26 |
27 | export function typeToIcon(type) {
28 | switch (type) {
29 | case 'is-info':
30 | return 'info-circle'
31 | case 'is-success':
32 | return 'check-circle'
33 | case 'is-warning':
34 | return 'exclamation-triangle'
35 | case 'is-danger':
36 | return 'exclamation-circle'
37 | default:
38 | return null
39 | }
40 | }
41 |
42 | export function getEventsAction(component) {
43 | return node => {
44 | const events = Object.keys(component.$$.callbacks);
45 | const listeners = [];
46 | events.forEach(event =>
47 | listeners.push(listen(node, event, e => bubble(component, e)))
48 | );
49 | return {
50 | destroy: () => {
51 | listeners.forEach(listener => listener());
52 | }
53 | };
54 | };
55 | }
56 |
--------------------------------------------------------------------------------