Improve naming, formatting and README

This commit is contained in:
Guilherme Cattani 2025-03-09 17:12:19 +01:00
parent 1163079592
commit cdd94926d4
7 changed files with 279 additions and 152 deletions

168
README.md
View file

@ -1,94 +1,106 @@
# Obsidian Sample Plugin
This is a sample plugin for Obsidian (https://obsidian.md).
This project uses TypeScript to provide type checking and documentation.
The repo depends on the latest plugin API (obsidian.d.ts) in TypeScript Definition format, which contains TSDoc comments describing what it does.
# CountdownTo
This sample plugin demonstrates some of the basic functionality the plugin API can do.
- Adds a ribbon icon, which shows a Notice when clicked.
- Adds a command "Open Sample Modal" which opens a Modal.
- Adds a plugin setting tab to the settings page.
- Registers a global click event and output 'click' to the console.
- Registers a global interval which logs 'setInterval' to the console.
![CountdownTo](./screenshot.png)
## First time developing plugins?
Track time until important deadlines, events, or milestones with visual progress indicators.
Quick starting guide for new plugin devs:
## Features
- Check if [someone already developed a plugin for what you want](https://obsidian.md/plugins)! There might be an existing plugin similar enough that you can partner up with.
- Make a copy of this repo as a template with the "Use this template" button (login to GitHub if you don't see it).
- Clone your repo to a local development folder. For convenience, you can place this folder in your `.obsidian/plugins/your-plugin-name` folder.
- Install NodeJS, then run `npm i` in the command line under your repo folder.
- Run `npm run dev` to compile your plugin from `main.ts` to `main.js`.
- Make changes to `main.ts` (or create new `.ts` files). Those changes should be automatically compiled into `main.js`.
- Reload Obsidian to load the new version of your plugin.
- Enable plugin in settings window.
- For updates to the Obsidian API run `npm update` in the command line under your repo folder.
- Create visual progress bars that count down to specific dates
- Different progress bar types: `Line`, `Circle`, `SemiCircle`, and `Square`
- Customizable appearance with color options
- Flexible date and time formatting using Luxon
- Custom info text with placeholders for dates, percentages, and durations
- Progress can be shown as forward progress or as a countdown (days until)
- Configurable completion messages
## Releasing new releases
## Manual Installation
- Update your `manifest.json` with your new version number, such as `1.0.1`, and the minimum Obsidian version required for your latest release.
- Update your `versions.json` file with `"new-plugin-version": "minimum-obsidian-version"` so older versions of Obsidian can download an older version of your plugin that's compatible.
- Create new GitHub release using your new version number as the "Tag version". Use the exact version number, don't include a prefix `v`. See here for an example: https://github.com/obsidianmd/obsidian-sample-plugin/releases
- Upload the files `manifest.json`, `main.js`, `styles.css` as binary attachments. Note: The manifest.json file must be in two places, first the root path of your repository and also in the release.
- Publish the release.
1. Download the latest release from the [GitHub releases page](https://github.com/guicattani/countdown-to/releases)
2. Extract the files to your Obsidian vault's plugins folder: `<vault>/.obsidian/plugins/countdown-to/`
3. Reload Obsidian
4. Enable the plugin in Obsidian settings under Community Plugins
> You can simplify the version bump process by running `npm version patch`, `npm version minor` or `npm version major` after updating `minAppVersion` manually in `manifest.json`.
> The command will bump version in `manifest.json` and `package.json`, and add the entry for the new version to `versions.json`
## How to Use
## Adding your plugin to the community plugin list
Create a countdown progress bar by adding a code block with the `progressbar` language identifier:
- Check the [plugin guidelines](https://docs.obsidian.md/Plugins/Releasing/Plugin+guidelines).
- Publish an initial version.
- Make sure you have a `README.md` file in the root of your repo.
- Make a pull request at https://github.com/obsidianmd/obsidian-releases to add your plugin.
## How to use
- Clone this repo.
- Make sure your NodeJS is at least v16 (`node --version`).
- `npm i` or `yarn` to install dependencies.
- `npm run dev` to start compilation in watch mode.
## Manually installing the plugin
- Copy over `main.js`, `styles.css`, `manifest.json` to your vault `VaultFolder/.obsidian/plugins/your-plugin-id/`.
## Improve code quality with eslint (optional)
- [ESLint](https://eslint.org/) is a tool that analyzes your code to quickly find problems. You can run ESLint against your plugin to find common bugs and ways to improve your code.
- To use eslint with this project, make sure to install eslint from terminal:
- `npm install -g eslint`
- To use eslint to analyze this project use this command:
- `eslint main.ts`
- eslint will then create a report with suggestions for code improvement by file and line number.
- If your source code is in a folder, such as `src`, you can use eslint with this command to analyze all files in that folder:
- `eslint .\src\`
## Funding URL
You can include funding URLs where people who use your plugin can financially support it.
The simple way is to set the `fundingUrl` field to your link in your `manifest.json` file:
```json
{
"fundingUrl": "https://buymeacoffee.com"
}
````markdown
```progressbar
title: Project Deadline
startDate: 2025-03-12
endDate: 2025-04-11
type: Circle
color: #ff5722
trailColor: #f5f5f5
progressType: countdown
infoFormat: {percent}% complete - {remaining} until {end(LLL d, yyyy)}
```
````
If you have multiple URLs, you can also do:
### Required Parameters
```json
{
"fundingUrl": {
"Buy Me a Coffee": "https://buymeacoffee.com",
"GitHub Sponsor": "https://github.com/sponsors",
"Patreon": "https://www.patreon.com/"
}
}
```
- `endDate`: The target date to count down to (ISO format: YYYY-MM-DDTHH:MM:SS)
- `startDate`: Start date for the progress calculation (ISO format: YYYY-MM-DDTHH:MM:SS)
## API Documentation
### Optional Parameters
See https://github.com/obsidianmd/obsidian-api
- `title`: Title of the countdown (show above the progress bar)
- `type`: Progress bar type - `line`, `circle`, `semicircle`, or `square` (defaults to `line`)
- `color`: Color for the progress bar (HEX format)
- `trailColor`: Color for the incomplete part of the progress bar (HEX format)
- `progressType`: `progress` (default) or `countdown`
- `onCompleteText`: Text to display when the countdown is complete
- `infoFormat`: Custom format for the information text
## Formatting Options
The `infoFormat` parameter supports various placeholders and Luxon formatting options:
### Basic Placeholders
- `{percent}` - Percentage of completion
- `{start}` - Start date (ISO format)
- `{end}` - End date (ISO format)
- `{current}` - Current date (ISO format)
- `{remaining}` - Remaining time in human-readable format
- `{elapsed}` - Elapsed time in human-readable format
- `{total}` - Total duration in human-readable format
### Luxon Formatting
You can format dates and durations using [Luxon's](https://moment.github.io/luxon/#/formatting?id=table-of-tokens) formatting syntax:
- `{start(format)}` - Format start date
- `{end(format)}` - Format end date
- `{current(format)}` - Format current date
- `{remaining(format)}` - Format remaining duration
- `{elapsed(format)}` - Format elapsed duration
- `{total(format)}` - Format total duration
Examples:
- `{end(LLL d, yyyy)}` displays the end date as "Apr 11, 2025"
- `{end(EEEE, MMMM d, yyyy)}` displays as "Thursday, April 11, 2025"
See the [Luxon formatting reference](https://moment.github.io/luxon/#/formatting?id=table-of-tokens) for all available format tokens.
## Configuration
You can configure default settings for all progress bars in the plugin settings:
1. Open Obsidian Settings
2. Navigate to the "Countdown To" plugin settings
3. Customize the default bar type, colors, progress type, and info format
All settings can be overridden in individual progress bar code blocks.
## Support
If you encounter any issues or have feature requests, please [open an issue](https://github.com/guicattani/countdown-to/issues) on GitHub.
## Credits
- Uses [progressbar.js](https://kimmobrunfeldt.github.io/progressbar.js/) for rendering progress bars
- Uses [Luxon](https://moment.github.io/luxon/) for date and time handling

221
main.ts
View file

@ -1,20 +1,23 @@
import { App, Plugin, PluginSettingTab, Setting } from 'obsidian';
import { App, Plugin, PluginSettingTab, Setting, Modal } from 'obsidian';
import { DateTime, Duration, Interval } from 'luxon';
import * as ProgressBar from 'progressbar.js';
interface ProgressBarSettings {
defaultBarColor: string;
defaultBarBackgroundColor: string;
defaultTrailColor: string;
defaultBarType: string;
defaultProgressType: string;
defaultOnCompleteText: string;
defaultProgressType: string;
defaultOnCompleteText: string;
defaultInfoFormat: string;
}
const DEFAULT_SETTINGS: ProgressBarSettings = {
defaultBarColor: '#4CAF50',
defaultBarBackgroundColor: '#e0e0e0',
defaultTrailColor: '#e0e0e0',
defaultBarType: 'Line',
defaultProgressType: 'forward',
defaultOnCompleteText: 'Completed!',
defaultProgressType: 'forward',
defaultOnCompleteText: '{title} is done!',
defaultInfoFormat: '{percent}% - {remaining} remaining',
}
export default class ProgressBarPlugin extends Plugin {
@ -41,14 +44,16 @@ export default class ProgressBarPlugin extends Plugin {
renderProgressBar(source: string, el: HTMLElement) {
try {
const params = this.parseProgressBarParams(source);
const containerEl = el.createDiv({ cls: 'progress-bar-container' });
const containerEl = el.createDiv({ cls: 'countdown-to-container' });
const startDate = params.startDate ? new Date(params.startDate) : new Date();
const endDate = new Date(params.endDate);
const currentDate = new Date();
const startDate = params.startDate ?
DateTime.fromISO(params.startDate) :
DateTime.now();
const endDate = DateTime.fromISO(params.endDate);
const currentDate = DateTime.now();
if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
containerEl.setText('Invalid date format. Please use YYYY-MM-DD format.');
if (!startDate.isValid || !endDate.isValid) {
containerEl.setText('Invalid date format. Please use ISO format (YYYY-MM-DDTHH:MM:SS).');
return;
}
@ -57,37 +62,64 @@ export default class ProgressBarPlugin extends Plugin {
return;
}
const totalDuration = endDate.getTime() - startDate.getTime();
const elapsedDuration = currentDate.getTime() - startDate.getTime();
let progress = Math.min(Math.max(elapsedDuration / totalDuration, 0), 1);
const totalInterval = Interval.fromDateTimes(startDate, endDate);
const elapsedInterval = Interval.fromDateTimes(startDate, currentDate);
const barColor = params.color || this.settings.defaultBarColor;
const barBgColor = params.backgroundColor || this.settings.defaultBarBackgroundColor;
const barType = params.type || this.settings.defaultBarType;
const progressType = params.progressType || this.settings.defaultProgressType;
const onCompleteText = params.onCompleteText || this.settings.defaultOnCompleteText;
const totalMillis = totalInterval.length();
const elapsedMillis = Math.min(elapsedInterval.length(), totalMillis);
let progress = Math.min(Math.max(elapsedMillis / totalMillis, 0), 1);
const barColor = params.color || this.settings.defaultBarColor;
const trailColor = params.trailColor || this.settings.defaultTrailColor;
const barType = params.type || this.settings.defaultBarType;
const progressType = params.progressType || this.settings.defaultProgressType;
const onCompleteText = params.onCompleteText || this.settings.defaultOnCompleteText;
const infoFormat = params.infoFormat || this.settings.defaultInfoFormat;
const progressBarEl = containerEl.createDiv({ cls: 'progress-bar-element' });
progressBarEl.addClass(`progress-bar-${barType.toLowerCase()}`);
const infoEl = containerEl.createDiv({ cls: 'progress-bar-info' });
const remainingTime = this.formatRemainingTime(endDate, currentDate);
if (progress >= 1) {
infoEl.setText(onCompleteText);
infoEl.setText(
onCompleteText.replace(/{title}/g, params.title || '')
);
} else {
if (progressType.toLowerCase() === 'countdown') {
infoEl.setText(`${remainingTime} until completion`);
} else {
infoEl.setText(`${Math.round(progress * 100)}% - ${remainingTime} remaining`);
}
let infoText = infoFormat;
const remainingInterval = Interval.fromDateTimes(currentDate, endDate);
const remainingDuration = remainingInterval.toDuration(['days', 'hours', 'minutes', 'seconds']);
const elapsedDuration = elapsedInterval.toDuration(['days', 'hours', 'minutes', 'seconds']);
const totalDuration = totalInterval.toDuration(['days', 'hours', 'minutes', 'seconds']);
infoText = infoText
.replace(/{start\((.*?)\)}/g, (_match: string, format: string) => startDate.toFormat(format))
.replace(/{end\((.*?)\)}/g, (_match: string, format: string) => endDate.toFormat(format))
.replace(/{current\((.*?)\)}/g, (_match: string, format: string) => currentDate.toFormat(format))
.replace(/{remaining\((.*?)\)}/g, (_match: string, format: string) => remainingDuration.toFormat(format))
.replace(/{elapsed\((.*?)\)}/g, (_match: string, format: string) => elapsedDuration.toFormat(format))
.replace(/{total\((.*?)\)}/g, (_match: string, format: string) => totalDuration.toFormat(format));
infoText = infoText
.replace(/{percent}/g, Math.round(progress * 100).toString())
.replace(/{start}/g, startDate.toISODate() || '')
.replace(/{end}/g, endDate.toISODate() || '')
.replace(/{current}/g, currentDate.toISODate() || '')
.replace(/{remaining}/g, this.formatDuration(remainingDuration))
.replace(/{elapsed}/g, this.formatDuration(elapsedDuration))
.replace(/{total}/g, this.formatDuration(totalDuration));
infoEl.setText(infoText);
}
let bar;
const commonOptions = {
strokeWidth: 4,
color: barColor,
trailColor: barBgColor,
trailColor: trailColor,
trailWidth: 1,
};
@ -119,14 +151,12 @@ export default class ProgressBarPlugin extends Plugin {
break;
}
// Animation support still needs some work
if (progressType.toLowerCase() === 'countdown') {
bar.set(1.0 - progress);
} else {
bar.set(progress);
}
if (progressType.toLowerCase() === 'countdown') {
bar.set(1.0 - progress);
} else {
bar.set(progress);
}
// Add title if provided
if (params.title) {
const titleEl = containerEl.createDiv({ cls: 'progress-bar-title' });
titleEl.setText(params.title);
@ -149,7 +179,6 @@ export default class ProgressBarPlugin extends Plugin {
}
});
// Ensure required parameters
if (!params.endDate) {
throw new Error('End date is required');
}
@ -157,17 +186,11 @@ export default class ProgressBarPlugin extends Plugin {
return params;
}
formatRemainingTime(endDate: Date, currentDate: Date) {
const remainingMs = endDate.getTime() - currentDate.getTime();
if (remainingMs <= 0) {
return 'Completed';
}
const seconds = Math.floor(remainingMs / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
formatDuration(duration: Duration): string {
const days = Math.ceil(duration.as('days'));
const hours = Math.ceil(duration.as('hours') % 24);
const minutes = Math.ceil(duration.as('minutes') % 60);
const seconds = Math.ceil(duration.as('seconds') % 60);
if (days > 0) {
return `${days} day${days > 1 ? 's' : ''}`;
@ -194,7 +217,8 @@ class ProgressBarSettingTab extends PluginSettingTab {
containerEl.empty();
containerEl.createEl('h2', {text: 'Progress Bar Settings'});
containerEl.createEl('h2', {text: 'Countdown To Settings'});
containerEl.createEl('a', {href: 'https://github.com/guicattani/countdown-to?tab=readme-ov-file#how-to-use', text: 'How to use'});
new Setting(containerEl)
.setName('Default bar type')
@ -211,10 +235,10 @@ class ProgressBarSettingTab extends PluginSettingTab {
}));
new Setting(containerEl)
.setName('Progress type')
.setDesc('Type of progress bar to display (forward or countdown)')
.setName('Default progress type')
.setDesc('Count as progress or as a countdown')
.addDropdown(dropdown => dropdown
.addOption('Forward', 'Forward')
.addOption('Progress', 'Progress')
.addOption('Countdown', 'Countdown')
.setValue(this.plugin.settings.defaultProgressType)
.onChange(async (value) => {
@ -222,6 +246,25 @@ class ProgressBarSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
}));
new Setting(containerEl)
.setName('Default info format')
.setDesc('Default format for the info text. Uses Luxon formatting (See format help button for a quick reference).')
.addTextArea(text => text
.setPlaceholder('{percent}% - {remaining} remaining')
.setValue(this.plugin.settings.defaultInfoFormat)
.onChange(async (value) => {
this.plugin.settings.defaultInfoFormat = value;
await this.plugin.saveSettings();
}))
.addExtraButton(button => {
button
.setIcon('help')
.setTooltip('Show format help')
.onClick(() => {
new LuxonFormatHelpModal(this.plugin.app).open();
});
});
new Setting(containerEl)
.setName('Default bar color')
.setDesc('Default color for the progress bar')
@ -235,9 +278,9 @@ class ProgressBarSettingTab extends PluginSettingTab {
new Setting(containerEl)
.setName('Default on complete text')
.setDesc('Default text to display when the progress bar is complete')
.setDesc('Default text to display when the progress is complete. Use {title} to display the title of the progress bar.')
.addText(text => text
.setPlaceholder('Completed!')
.setPlaceholder('{title} is done!')
.setValue(this.plugin.settings.defaultOnCompleteText)
.onChange(async (value) => {
this.plugin.settings.defaultOnCompleteText = value;
@ -245,14 +288,76 @@ class ProgressBarSettingTab extends PluginSettingTab {
}));
new Setting(containerEl)
.setName('Default background color')
.setDesc('Default background color for the progress bar')
.setName('Default trail color')
.setDesc('Default trail color for the progress bar (the incomplete part)')
.addText(text => text
.setPlaceholder('#e0e0e0')
.setValue(this.plugin.settings.defaultBarBackgroundColor)
.setValue(this.plugin.settings.defaultTrailColor)
.onChange(async (value) => {
this.plugin.settings.defaultBarBackgroundColor = value;
this.plugin.settings.defaultTrailColor = value;
await this.plugin.saveSettings();
}));
containerEl.createEl('i', {text: 'All settings can be overridden in the markdown code block.'});
}
}
class LuxonFormatHelpModal extends Modal {
constructor(app: App) {
super(app);
}
onOpen() {
const {contentEl} = this;
contentEl.createEl('h2', {text: 'Info Format Help'});
contentEl.createEl('h3', {text: 'Placeholders'});
const placeholdersList = contentEl.createEl('ul');
placeholdersList.createEl('li', {text: '{percent} - Percentage of completion'});
placeholdersList.createEl('li', {text: '{start} - Start date (ISO format)'});
placeholdersList.createEl('li', {text: '{end} - End date (ISO format)'});
placeholdersList.createEl('li', {text: '{current} - Current date (ISO format)'});
placeholdersList.createEl('li', {text: '{remaining} - Remaining time'});
placeholdersList.createEl('li', {text: '{elapsed} - Elapsed time'});
placeholdersList.createEl('li', {text: '{total} - Total duration'});
contentEl.createEl('h3', {text: 'Formatting'});
contentEl.createEl('p', {text: 'You can use Luxon formatting for dates:'});
const luxonList = contentEl.createEl('ul');
luxonList.createEl('li', {text: '{start(format)} - Format start date'});
luxonList.createEl('li', {text: '{end(format)} - Format end date'});
luxonList.createEl('li', {text: '{current(format)} - Format current date'});
luxonList.createEl('li', {text: '{remaining(format)} - Format remaining time'});
luxonList.createEl('li', {text: '{elapsed(format)} - Format elapsed time'});
luxonList.createEl('li', {text: '{total(format)} - Format total duration'});
contentEl.createEl('a', {href: 'https://moment.github.io/luxon/#/formatting?id=table-of-tokens', text: 'Luxon Formatting Reference'});
contentEl.createEl('h3', {text: 'Examples'});
const examplesList = contentEl.createEl('ul');
examplesList.createEl('li', {text: '{percent}% complete - {remaining} left'});
examplesList.createEl('li', {text: 'Started on {start(LLL d)}, ends on {end(LLL d, yyyy)}'});
examplesList.createEl('li', {text: '{elapsed} elapsed out of {total} total'});
contentEl.createEl('h3', {text: 'Common Luxon Formats'});
const formatsTable = contentEl.createEl('table');
const headerRow = formatsTable.createEl('tr');
headerRow.createEl('th', {text: 'Format'});
headerRow.createEl('th', {text: 'Output'});
const addFormatRow = (format: string, output: string) => {
const row = formatsTable.createEl('tr');
row.createEl('td', {text: format});
row.createEl('td', {text: output});
};
addFormatRow('yyyy-MM-dd', '2025-04-11');
addFormatRow('LLL d, yyyy', 'Apr 11, 2025');
addFormatRow('EEEE, MMMM d, yyyy', 'Thursday, April 11, 2025');
addFormatRow('d MMMM yyyy', '11 April 2025');
}
onClose() {
const {contentEl} = this;
contentEl.empty();
}
}

View file

@ -1,11 +1,10 @@
{
"id": "obsidian-progress-bar",
"name": "Progress Bar",
"id": "obsidian-countdown-to",
"name": "Countdown To",
"version": "1.0.0",
"minAppVersion": "0.15.0",
"description": "Create countdown progress bars in your notes",
"author": "Gui Cattani",
"authorUrl": "https://github.com/guicattani",
"fundingUrl": "https://obsidian.md/pricing",
"isDesktopOnly": false
}

22
package-lock.json generated
View file

@ -1,17 +1,19 @@
{
"name": "obsidian-sample-plugin",
"name": "obsidian-progress-bar",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "obsidian-sample-plugin",
"name": "obsidian-progress-bar",
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"luxon": "^3.5.0",
"progressbar.js": "^1.1.1"
},
"devDependencies": {
"@types/luxon": "^3.4.2",
"@types/node": "^16.11.6",
"@types/progressbar.js": "^1.1.7",
"@typescript-eslint/eslint-plugin": "5.29.0",
@ -599,6 +601,13 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/luxon": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.4.2.tgz",
"integrity": "sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/node": {
"version": "16.18.125",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.125.tgz",
@ -1824,6 +1833,15 @@
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"license": "MIT"
},
"node_modules/luxon": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.5.0.tgz",
"integrity": "sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==",
"license": "MIT",
"engines": {
"node": ">=12"
}
},
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",

View file

@ -1,5 +1,5 @@
{
"name": "obsidian-progress-bar",
"name": "obsidian-countdown-to",
"version": "1.0.0",
"description": "Create countdown progress bars in your notes",
"main": "main.js",
@ -17,6 +17,7 @@
"author": "Gui Cattani",
"license": "MIT",
"devDependencies": {
"@types/luxon": "^3.4.2",
"@types/node": "^16.11.6",
"@types/progressbar.js": "^1.1.7",
"@typescript-eslint/eslint-plugin": "5.29.0",
@ -28,6 +29,7 @@
"typescript": "4.7.4"
},
"dependencies": {
"luxon": "^3.5.0",
"progressbar.js": "^1.1.1"
}
}

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View file

@ -1,13 +1,4 @@
/*
This CSS file will be included with your plugin, and
available in the app when your plugin is enabled.
If your plugin does not need CSS, delete this file.
*/
.progress-bar-container {
.countdown-to-container {
position: relative;
margin: 20px 0;
padding: 10px;